none
Website edit form optimalisation suggestions

    General discussion

  • Hello,

    this is a copy of my reply from this topic:

    http://social.msdn.microsoft.com/Forums/en-US/wspsupport/thread/751fe98d-f289-4aa5-ad90-a782004fe111

    I've decided to start a new discussion because my reply is mostly related to WSP development.

    "Hello Pavel,

    thank you for great functionality. I've compiled latest 1.2.0 beta and webmatrix profile generation is working ok but I've noticed (and my customers) that loading website edit page is taking longer than before. I've checked "public override WebSite GetSite(string siteId)" function what is being runned during website edit for loading and there is a lot of functions which could be removed based on hosting plan quotas. Examples:

    • Helicon Ape
    • FrontPage Server Extensions
    • ColdFusion
    • WSP SecureFolders module checking

    There is another weird thing: at the end of GetSite function there are:

    site.SiteState = GetSiteState(siteId);

    site.SecuredFoldersInstalled = false;

    site.SiteState = GetSiteState(siteId);

    Why load sitestate twice? Why not load SiteState already in "public WebSite GetWebSiteFromIIS(string siteId)" function?

    For example in function "public WebSite GetWebSiteFromIIS(string siteId)" just after "webSite.SiteId = webSite.Name = iisObject.Name;" add:

        webSite.SiteState = ServerState.Unknown;
        //
        switch (srvman.Sites[siteId].State)
        {
         case ObjectState.Started:
          webSite.SiteState = ServerState.Started;
          break;
         case ObjectState.Starting:
          webSite.SiteState = ServerState.Starting;
          break;
         case ObjectState.Stopped:
          webSite.SiteState = ServerState.Stopped;
          break;
         case ObjectState.Stopping:
          webSite.SiteState = ServerState.Stopping;
          break;
        }
    

    I have also suggestion regarding this line:

    "ReadWebDeployPublishingAccessDetails(site);" Why check everytime:

    iisObject.WebDeployPublishingAvailable = IsWebDeployInstalled() && IsWebManagementServiceInstalled();

    when website details are being loaded? This should be covered in IIS7 provider settings and after checking that they are available don't check for them again since this slows down website page loading for no reason."

    Friday, April 22, 2011 12:06 PM

All replies

  • P.S. Don't forget about this:

    http://social.msdn.microsoft.com/Forums/en-US/wspsupport/thread/7ce6f769-24eb-4df2-a395-147e7a03ca58/#9c54013a-4966-4a7d-a7c3-a42b643b6a86

    I will copy and paste my responses from this topic here so it could be all in one place:

    ----->

    I'm wondering why IIS (applicationHost.config) is used for bandwidth calculation? Is it only used to fetch website logs path? In IIs70.cs file from WebsitePanel.Providers.Web.IIs70 we have

    public override ServiceProviderItemBandwidth[] GetServiceItemsBandwidth(ServiceProviderItem[] items, DateTime since)

    method where we have:

    ..
    
          WebSite site = GetSite(item.Name);
          string siteId = site[WebSite.IIS7_SITE_ID];
          string logsPath = Path.Combine(site.LogsPath, siteId);
    
    ..
    

    where as you can see opening whole website using IIS is only used for fetching website logs directory. I think saving this value to WSP Enterprise DB (maybe this value is already in this DB? I didn't checked yet) could veeeery shorten whole bandwidth calculation process and solve issue with applicationHost.config file.

    What do you think?

    ---

    I've checked WSP Enterprise DB and I didn't found log directory stored anywhere (but there is data directory stored). Ok so I think it could be solved by adding log path rows to the

    ServiceItemProperties

    table in WSP Enterprise DB. Row could be similar to this:

    ItemID autoincrement

    PropertyName something like LogPath

    PropertyValue "X:\HostingSpaces\USERNAME\website.com\logs\W3SVCxxx"

    ---

    Exactly the same problem occurs with diskspace calculation.

    Method called

    public override ServiceProviderItemDiskSpace[] GetServiceItemsDiskSpace(ServiceProviderItem[] items)

    There is WebSite site = GetSite(item.Name); used only for getting logs path.

    ---

    There is one more thing maybe which could be checked. When website settings page is loaded in WSP is uses GetSite method. This method uses other methods to load all website settings and all of them are opening their own GetServerManager instance:

                using (var srvman = webObjectsSvc.GetServerManager())
                {

                ...

                }

    wouldn't it be better to open one global srvman and use it in all methods? This is just a though and I'm not sure if this could help so maybe someone could investigate this?

    Saturday, April 23, 2011 7:48 AM
  • I've found another optimalisations which will shorten website creation a lot.

    Affected file:

    IIS7.cs

    Affected functions:

    private void SetWebSiteApplicationPool(WebSite site, bool createAppPools)

    private void DeleteDedicatedPoolsAllocated(string siteName)

    Descrtiption:

    mentioned functions are opening new instance of webObjectsSvc.GetServerManager() in every foreach when creating or deleting application pool. I've moved:

    using (var srvman = webObjectsSvc.GetServerManager())
            {
    

    outside foreach loop.

    Also in every foreach pass there is runned:

    srvman.CommitChanges();
    

    which also can be moved outside foreach loop (in both creating and deleting application pools functions).

    As example part of application pools deletion function:

            using (var srvman = webObjectsSvc.GetServerManager())
            {
              foreach (var item in dedicatedPools)
              {
    
                //
                string poolName = WSHelper.InferAppPoolName(item.Name, siteName, item.Mode);
                //
                ApplicationPool pool = srvman.ApplicationPools[poolName];
                if (pool == null)
                  continue;
                //
                srvman.ApplicationPools.Remove(pool);
                //
              }
              srvman.CommitChanges();
            }
    

    As you can see after making this modifications all application pools are added to server manager instance and after looping and adding all of them there is runned CommitChanges functions which adds them all at once. In short we have only one server manager instance except of 5 and we are commiting only one CommitChange instead o 5. Believe me it make a BIG difference.

     

     

    Saturday, April 23, 2011 12:09 PM
  • There is another thing which could be considered during website creation and it is website bindings.

    In public override string CreateSite(WebSite site) function we have

    webObjectsSvc.UpdateSiteBindings(site.SiteId, site.Bindings);

    which runs function:

     

    		public void UpdateSiteBindings(string siteId, ServerBinding[] bindings)
    		{
    			// Ensure web site exists
    			if (!SiteExists(siteId))
    				return;
    			//
    			SyncWebSiteBindingsChanges(siteId, bindings);
    		}
    

    and in this function we see SiteExist function which is:

     

      public bool SiteExists(string siteId)
      {
    			using (var srvman = GetServerManager())
    			{
    				return (srvman.Sites[siteId] != null);
    			}
      }
    
    so we have another server manager instance. I don't see a point of checking if website exist during it's creation since if something would go wrong before website bindings creation it would return error anyway.

     

    So instead running mentioned:

    webObjectsSvc.UpdateSiteBindings(site.SiteId, site.Bindings);

    we could run (we must change SyncWebSiteBindingsChanges from private to public):

    webObjectsSvc.SyncWebSiteBindingsChanges(site.SiteId, site.Bindings);

    There is also another thing which I have not mentioned in my first post and it is function:

    UpdateCgiBinFolder(site);

    from public override string CreateSite(WebSite site) which also should not be runned if hosting plan quota does not contain cgi-bin.

    EDIT: Mentioned cgi-bin folder and setting binding functions are also present in public override void UpdateSite(WebSite site) so mentioned optimalisations could be also implemented in this function.

    Saturday, April 23, 2011 12:39 PM
  • In

    public WebSite GetWebSiteFromIIS(string siteId)

    there is no need to call

    public string GetWebSiteIdFromIIS(string siteId, string format)

    and open another srvman instance because there is already one open at the beginning of GetWebSiteFromIIS function (IIs7.cs).

    So for getting siteId and formatting make simple if (which is a copy what is done in GetWebSiteFromIIS but without using another srvman instance):

            if (String.IsNullOrEmpty("W3SVC{0}"))
            {
              webSite[WebSite.IIS7_SITE_ID] = Convert.ToString(iisObject.Id);
            }
            else
            {
              webSite[WebSite.IIS7_SITE_ID] = String.Format("W3SVC{0}", iisObject.Id);
            }
    

    Sunday, May 01, 2011 3:34 PM
  • Sometimes users are deleting their website directories before they remove website from WSP and this is causing some problems because they can't do anything (and not all of them are recreating directory structure so website could be editable again). This can be solved by adding:

     

            if (!FileUtils.DirectoryExists(iisObject.Applications["/"].VirtualDirectories["/"].PhysicalPath))
              FileUtils.CreateDirectory(iisObject.Applications["/"].VirtualDirectories["/"].PhysicalPath);
            if (!FileUtils.DirectoryExists(iisObject.Applications["/"].VirtualDirectories["/"].PhysicalPath.Replace("wwwroot","data")))
              FileUtils.CreateDirectory(iisObject.Applications["/"].VirtualDirectories["/"].PhysicalPath.Replace("wwwroot", "data"));
            if (!FileUtils.DirectoryExists(iisObject.Applications["/"].VirtualDirectories["/"].PhysicalPath.Replace("wwwroot", "logs")))
              FileUtils.CreateDirectory(iisObject.Applications["/"].VirtualDirectories["/"].PhysicalPath.Replace("wwwroot", "logs"));
    
    in public WebSite GetWebSiteFromIIS(string siteId) function just after var iisObject = srvman.Sites[siteId];

    Sunday, May 01, 2011 4:09 PM
  • We have implemented the above fix in our environment as this was happening a few times / day.

    Thanks!

    Tuesday, August 02, 2011 6:29 AM
  • I am waiting to implement these improvements!
    Friday, August 05, 2011 1:10 AM
  • Hi Webio,

    First, I appreciate your information. Please teach me a little.

        if (!FileUtils.DirectoryExists(iisObject.Applications["/"].VirtualDirectories["/"].PhysicalPath))
         FileUtils.CreateDirectory(iisObject.Applications["/"].VirtualDirectories["/"].PhysicalPath);
        if (!FileUtils.DirectoryExists(iisObject.Applications["/"].VirtualDirectories["/"].PhysicalPath.Replace("wwwroot","data")))
         FileUtils.CreateDirectory(iisObject.Applications["/"].VirtualDirectories["/"].PhysicalPath.Replace("wwwroot", "data"));
        if (!FileUtils.DirectoryExists(iisObject.Applications["/"].VirtualDirectories["/"].PhysicalPath.Replace("wwwroot", "logs")))
         FileUtils.CreateDirectory(iisObject.Applications["/"].VirtualDirectories["/"].PhysicalPath.Replace("wwwroot", "logs"));
    
    in public WebSite GetWebSiteFromIIS(string siteId) function just after var iisObject = srvman.Sites[siteId]; 


    I am trying to above custom. However, I can not find where to insert the code. I've downloaded the source code from following link.

    http://websitepanel.codeplex.com/SourceControl/list/changesets

    I'm sorry, could you teach a little more in detail?

    Thanks,

    Friday, August 05, 2011 10:32 AM
  • Hello,

    I think I've managed to speed things a little.

    All changes must be made in WebsitePanel.Providers.Web.IIs70 project from WSP Server solution.

    First you must change whole content of file ConfigurationModuleService.cs to:

     

    namespace WebsitePanel.Providers.Web.Iis.Common
    {
        using System;
        using System.Collections.Generic;
        using System.Text;
    
        using Microsoft.Web.Administration;
        using Microsoft.Web.Management.Server;
    
        public abstract class ConfigurationModuleService
        {
            private static ServerManager _instance;
            public static ServerManager Instance
            {
                get
                {
                    if (_instance == null)
                        _instance = new ServerManager();
                    return _instance;
                }
            }
    
    		/// <summary>
    		/// We'll use it in the future to implement management of web farm with shared configuration enabled
    		/// </summary>
    		/// <returns></returns>
    		internal ServerManager GetServerManager()
    		{
                return Instance;
    		}
        }
    }
        
    
    as you can see I've changed this:

     

     

    public abstract class ConfigurationModuleService
        {
      /// <summary>
      /// We'll use it in the future to implement management of web farm with shared configuration enabled
      /// </summary>
      /// <returns></returns>
      internal ServerManager GetServerManager()
      {
       return new ServerManager();
      }
        }
    

     


    which basically was opening new instance everytime GetServerManager was runned and there is about one hundred lines containing this function in IIS7 project.

    Ok so after changing this file you must replace all (I mean ALL) get server instances which are runned by "using" command according to this example:

     

    using (var srvman = ....GetServerManager())
    

     

    to

     

    var srvman = ....GetServerManager();
    

    There are a lot of GetServerManager() using sections where this file is opened by different class so you must look for "GetServerManager())" because this is the common part of all sections which start with using and which use this function.

    So instead of:

     

    using (var srvman = ....GetServerManager())
    {
    ...
    }
    

     

    you should have (without brackets):

     

    var srvman = ...GetServerManager();
    ...
    
    

     

    This solution noticeably decreased CPU and memory usage of WSP Server component and allowed to speed things a little in control panel when opening or creating websites. I didn't tested yet bandwidth and diskspace calculation task.

    P.S. This is strictly dev post and I don't have time to upload dlls somewhere (especially that I have other custom changes to IIS sources) so you know .. leave it or take it. I would love to see someone taking a look at my code and correct it a little (some disposing etc).

    EDIT: Sorry but it still uses a lot of memory especially when performing calculation so this is not 100% solution for our problem. At least now I can edit website settings when calculation is being done and actually opening website settings is taking only few seconds.
    • Edited by Webio Tuesday, October 11, 2011 6:23 AM
    Monday, October 10, 2011 9:47 PM
  • Hi webio,

    Thank you for your great info. I'll try it later!

    Wednesday, October 12, 2011 10:58 AM
  • Hi,

    Now, I'm trying this optimisation. Could you please teach me some point?

     

    1. ConfigurationModuleService.cs

    If I don't specify Microsoft.Web.Administration in the using directive, a reference error occurs.  Therefore, I have left the using directive as follows.
    Is this correct?

        using Microsoft.Web.Administration;

        public abstract class ConfigurationModuleService
        {
            /// <summary>
            /// We'll use it in the future to implement management of web farm with shared configuration enabled
            /// </summary>
            /// <returns></returns>
            internal ServerManager GetServerManager()
            {
                return new ServerManager();
            }
        }

     

    2. IIs70.cs

    The scope declaration error occurred at some places.  Error details is below.

    A local variable named 'srvman cannot be declared in this scope because it would give a different meaning to 'srvman, which is already used in a 'child' scope to denote something else.

        var srvman = webObjectsSvc.GetServerManager();
        //
        Configuration appConfig = srvman.GetApplicationHostConfiguration();
        //
        ConfigurationSection modulesSection = appConfig.GetSection(Constants.ModulesSection, siteId);
        //
        ConfigurationElementCollection modulesCollection = modulesSection.GetCollection();
        //
        ConfigurationElement moduleAdd = modulesCollection.CreateElement("add");
        //
        moduleAdd["name"] = Constants.WEBSITEPANEL_IISMODULES;
        moduleAdd["type"] = SecureFoldersModuleAssembly;
        // Enable module for all content despite ASP.NET is enabled or not
        moduleAdd["preCondition"] = "";
        //
        modulesCollection.Add(moduleAdd);
        //
        srvman.CommitChanges();

    In this case, how should I do?

    Thursday, October 13, 2011 6:58 AM
  • Ad.1. Yes you are right. Usings must be left intact.

    Ad.2. I've made some another changes in IIS7.cs file and my srvman instance is initialised at the top of II7.cs file by:

    ServerManager srvman = new WebObjectsModuleService().GetServerManager();

    in

     

    public class IIs70 : IIs60, IWebServer

        {

    just after 

    private HttpRedirectModuleService httpRedirectSvc;

    and before Constants section.

    so all existing "var srvman = webObjectsSvc.GetServerManager();" (and similar opened using different classes in place where "webObjectsSvc" is) lines shoudl be removed (only from IIS7.cs file). Keep in mind that there are also servermanages instanced opened under different variable like "serverManager".

    My solution could be called a hack (but on the other hand it introduces proper way of handling servermanager in ConfigurationModuleService.cs file using Singleton) and it is not solving a lot of problems but at least it allows to open website settings in normal time.

    P.S. I saw also in file DelegationRulesModuleService.cs opening ServerManager not using ConfigurationModuleService.cs but just new ServerManager(); which is opening another instance next to one opened from ConfigurationModuleService so I've also renamed them to "var srvman = GetServerManager();"

    • Edited by Webio Thursday, October 13, 2011 7:34 AM
    Thursday, October 13, 2011 7:32 AM
  • Hi,

    Thank you for teaching carefully. Finally, I could optimize the WSP based on your opinion. In my case, It brought the respectively following results.

    Opening Website Property
    Before: 69seconds
    After: 37seconds

    Server Status
    OS: Windows Server 2008 R2 SP1
    CPU: Xeon L5640 @ 2.27GHz
    RAM: 12GB
    Number of Sites: about 1400
    AppHostConfig Size: about 5.7MB

    Although not shortened till few seconds, it became about half.  This is a very big step forward for me.

    Note:
    For above Ad2, the error seems to occur during removal of the site.(May only occur in my case...)  Therefore, this optimization is not included in the above result.

    Error detail is

    System.IO.FileLoadException: FileName: \\?\C:\Windows\system32\inetsrv\config\applicationHost.config
    Error: Cannot commit configuration changes because the file has changed on disk

       at Microsoft.Web.Administration.Interop.AppHostWritableAdminManager.CommitChanges()
       at Microsoft.Web.Administration.Configuration.CommitChanges()
       at Microsoft.Web.Administration.ConfigurationManager.CommitChanges()
       at Microsoft.Web.Administration.ServerManager.CommitChanges()
       at WebsitePanel.Providers.Web.IIs70.DeleteDedicatedPoolsAllocated(String siteName)

    When I checked, the site was deleted, but the application pool and the site user remained.

    Thursday, October 13, 2011 11:23 AM
  • Note:

    For above Ad2, the error seems to occur during removal of the site.(May only occur in my case...)  Therefore, this optimization is not included in the above result.

    Error detail is

    System.IO.FileLoadException: FileName: \\?\C:\Windows\system32\inetsrv\config\applicationHost.config
    Error: Cannot commit configuration changes because the file has changed on disk

       at Microsoft.Web.Administration.Interop.AppHostWritableAdminManager.CommitChanges()
       at Microsoft.Web.Administration.Configuration.CommitChanges()
       at Microsoft.Web.Administration.ConfigurationManager.CommitChanges()
       at Microsoft.Web.Administration.ServerManager.CommitChanges()
       at WebsitePanel.Providers.Web.IIs70.DeleteDedicatedPoolsAllocated(String siteName)

    When I checked, the site was deleted, but the application pool and the site user remained.

    Yep. This is the thing which needs to be investigated. I think this is related to opening only one (or few more) instances of ServerManager which is not disposed after operation. Like I said this is only a hack and I can't give guarantee that it will work correctly.

    I was trying to "fight" with this problem by adding another internal method to ConfigurationModuleService.cs file which is:

            internal void Unset()
            {
                _instance.Dispose();
                _instance = null;
            }
    

    then replacing in IIS7.cs

    private WebObjectsModuleService webObjectsSvc;

    with

    private WebObjectsModuleService webObjectsSvc = new WebObjectsModuleService();

    and after every srvman.CommitChanges(); I'm running

    webObjectsSvc.Unset();

    which should destroy ServerManager instance.

    The most important thing is that I'm not giving any guarantee that this will work correctly. I'm not a regular programmer so I could made some simple mistakes here but I'm hoping that will give some start point for fixing IIS7 provider.

    Thursday, October 13, 2011 11:52 AM
  • Hi Matt,

    > The most important thing is that I'm not giving any guarantee that this will work correctly.

    Okay. I see. In advance, I am performing the check of operation by the test machine. I understand your remark well and am doing this work...
    Although I don't have knowledge about development at all, I am glad if I can cooperate in the improvement of WSP!

    Then,

    When adding internal void Unset(), the following errors occurred.

    The name '_instance' does not exist in the current context.

     

    Possibly, how to write I may be wrong. Is my ConfigurationModuleService.cs correct ?

        using Microsoft.Web.Administration;

        public abstract class ConfigurationModuleService
        {
            /// <summary>
            /// We'll use it in the future to implement management of web farm with shared configuration enabled
            /// </summary>
            /// <returns></returns>
            internal ServerManager GetServerManager()
            {
                return new ServerManager();
            }
            internal void Unset()
            {
                _instance.Dispose();
                _instance = null;
            }
        }

    Friday, October 14, 2011 5:07 AM
  • Hello,

    I think you should for now return to oryginal/previous IIS7 provider version because as far I can see it allows load website settings faster but when it comes to everything related to updating website very often is returned error "Cannot commit configuration changes because the file has changed on disk". I'll try to find a way to use this solution but for now my advice is to return to previous version.

    Regards

    Friday, October 14, 2011 11:33 AM
  • Hi,

    Sorry for the late reply. OK, I will return to oryginal IIS provider. If there is update in this issue, please let me know :)


    • Edited by Ke-i Monday, October 17, 2011 1:41 AM
    Monday, October 17, 2011 1:40 AM
  • Does anyone have any idea how to solve this problem? Does anyone have looked at the WSP IIS7 provider sources?
    Tuesday, November 08, 2011 9:44 AM
  • I've been troubleshooting this same issue (and made some of the same changes you did before I found this thread). Seems to be a problem with Microsoft.Web.Administration: http://forums.iis.net/p/1180452/2013775.aspx

    Jeff Graves, ORCS Web, Inc.

    Wednesday, February 08, 2012 6:25 PM
  • Hi Guys,

    I still get this after the update to 1.2.1. Muuuch Less than before so definitely working better.

    Server was unable to process request. ---> Filename: \\?\C:\Windows\system32\inetsrv\config\applicationHost.config
    Error: Cannot commit configuration changes because the file has changed on disk

    I get one a day or so. I have 2200 domains on 1 server and setup a new server to handle new domains now.

    Could it be because of the number of domains?

    Any advice?

    Friday, June 22, 2012 7:11 AM
  • Server was unable to process request. ---> Filename: \\?\C:\Windows\system32\inetsrv\config\applicationHost.config
    Error: Cannot commit configuration changes because the file has changed on disk

    I get one a day or so. I have 2200 domains on 1 server and setup a new server to handle new domains now.

    Could it be because of the number of domains?

    Any advice?

    My first question would be: Are you using WHMCS?

    As it has been a confirmed bug by WHMCS and their api that this happens when there are multiple sites scheduled for deletion using WHMCS

    (the api pretty much tries to delete everything at once BUT with 1 command for each.. meaning the file is in use by it's own api already and has been changed by the other commands so it can't save).

    Incase your answer to using WHMCS is yes: it's not about the number of domains but about the amount scheduled for deletion etc by whmcs. (hopefuly in the future they can implement a queue or some other solution to this issue).

    Incase your answer is no: Do you use any loadbalancer software? or anything else that contacts the IIS Config and makes updates/changes to it? .

    To summ it up: this problem is caused by 3rd party applications making changes to the IIS configuration (adding/removing/editing the IIS Configuration). It is therefor not Directly related to WSP.


    Key4ce - IT professionals: www.key4ce.eu

    Friday, June 22, 2012 8:11 AM
    Moderator
  • This is not related to WHMCS for sure because I'm getting also this error during various operations (updating od deleting website). This is probably related to opening and closing servermanager instances in IIS7 provider in various of methods. Generally this is issue with IIS7 applicationHost.config file handling on higher load. For example 2200 domains * 5 application pools gives 10000 XML entries only for application pools and this must be traversed everytime this file is being accessed.

    I think it was confirmed by MS and in IIS8 it has been optimised:

    http://weblogs.asp.net/owscott/archive/2012/03/01/what-s-new-in-iis-8.aspx

    "Configuration Scale

    The IIS configuration files (e.g. applicationHost.config) can handle very large files with ease now.  There are substantial performance improvements in the upcoming version. Only administrators with large numbers of sites on the same server or server farm (think thousands) would have noticed before, but for large scale performance the new changes are paving the way for huge scale."

    IIS8 will also allow to run more SSL secured websites on single IP address which is a great feature (I hope it will work without problems).

    EDIT: WHMCS has no access to IIS API (it accesses WSP Enterprise API) so telling that this is related to 3rd party applications is wrong.
    • Edited by Webio Friday, June 22, 2012 8:31 AM
    Friday, June 22, 2012 8:26 AM
  • EDIT: WHMCS has no access to IIS API (it accesses WSP Enterprise API) so telling that this is related to 3rd party applications is wrong.

    Sorry but that by a fact IS already confirmed by Matt (owner of WHMCS) it is not about direct access but the way how it tries to update /make changes at once.

    This whole error is as literal as it can be.. Something or someone has updated applicationHost.config before you applied your own changes.

    (which is usually done by 3rd party app's). Higher load ofcourse can also help duo to sessions and changes in between the time you opened - and saved your changes (and again generating the error because the file literally has changed inbetween that time).

    Hopefully that last bit has changed by MS (accordingly)

    however saying 3rd party app's don't cause this makes your whole mindset wrong as again.. this is already confirmed for multiple applications making WHMCS the most used one by the hosts (for which i mentioned it as it will give you this error with even 5 - 10 sites.. aslong as you schedule multiple for deletion :P)


    Key4ce - IT professionals: www.key4ce.eu

    Friday, June 22, 2012 8:42 AM
    Moderator
  • I don't know what Matt has checked but I'm using WHMCS for about two years, I wrote various hooks for it and I'm also using decoded websitepanel server module which I've modified a little bit so I know it inside out and this is for sure not the problem in 95% of issues with applicationHost.config file.

    Just like I said I'm getting applicationHost.config errors in 99% during website creating, editing or deleting mostly in high usage hours. During this time no other software is using IIS for any other operations.

    Regarding WHMCS this is probably true when WHMCS is trying to delete X accounts during cron job this can cause problems but this is problem with WSP because WHMCS is only contacting WSP Enterprise API and WSP Enterprise is scheduling account deletions which can be confirmed by checking Running tasks in WSP Portal during WHMCS cron job.

    EDIT: Actually I'm wrong. This is not a problem with WSP but with IIS API which can't handle higher load for accessing applicationHost.config file.

    EDIT2: After releasing by MS first informations about IIS8 I've dropped this topic and I'm waiting for releasing of final version of Windows Server 8. I hope they really optimised access to this configuration file.


    • Edited by Webio Friday, June 22, 2012 8:59 AM
    Friday, June 22, 2012 8:56 AM
  • Alright.. so.. i was wrong about the high load part i never really realized that (as we just loadbalance some high load sites but the sites it self are only few :-))

    Api part.. It is indeed with the cron job (not manual deletion) i think WHMCS and WSP can both make the solution for it.. WHCMS : don't push all deletions at once (make something like a queue ) and WSP --> shouldn't accept multiple at once :-)

    Definitely some improvement for both to mention (as this is an existing issue which applies to most hosts i guess though the situation shouldn't be common for WHMCS do want to delete many sites at once if not only that it's bad for your business haha ;-))

    IIS8.. hopefully sorts the high load end though i would also look for alternatives (like running multiple IIS servers avoiding the 1000's of sites on one server) if not only that MS mentions improvement and not fix ;-) (or simply the fact that it's best to have some alternative routes to solve an issue in case the most wanted one didn't quite work ;-))


    Key4ce - IT professionals: www.key4ce.eu

    Friday, June 22, 2012 9:11 AM
    Moderator
  • We will see how it will work under IIS8.

    Regarding avoiding 1000s of sites on one IIS I think this is not a solution (or it should not be :) ). New IIS means new Windows so new licenses for system and for everything related to hosting environment (backup software, other modules like Helicon Ape etc.).

    WHMCS is very flexible solution and I'm sure it can be modified to set X hosting account deletions per day but just like I wrote 95% of my issues with applicationHost.config file are related to creaging, editing or deleting websites by customers.

    Friday, June 22, 2012 9:26 AM
  • True.. well not a solution of the problem but an avoidance of the problem.

    OS System (atleast if you got hosting licenses from MS) actually doesn't matter that much you mostly pay for users/sites ^^

    But i do understand it is not a favourable one (modules, extra system etc) :-)

    For WHMCS /WSP Api i have forwarded the issue to Omar, hopefully it will be picked up and be fixed on the WSP Api base (as i guess the best solution "for all" will lay in how WSP handles the requests rather then the amount of requests ^^)

    But indeed.. separated issues in this case (yet the same error - which made me think it was related :-))


    Key4ce - IT professionals: www.key4ce.eu

    Friday, June 22, 2012 9:37 AM
    Moderator
  • Biggest performance gain would be by saving website settings to DB but this would take a lot of rewriting in WSP code. In my opinion MS has made big mistake by using XML file for storing all IIS settings in one file. Some simple file DB system like SQL Server CE or anything similar would be probably performing a lot better.
    Friday, June 22, 2012 9:46 AM
  • You both making some good points.

    Webio's point is the most important in my opinion. Had I known about the WSP applicationHost.config file issue I would have never purchased a web server that can handle around 4000 domains, I basically wasted my money. I should have planned to purchase four web servers that handle up to 1000 domain each.

    If there's a WSP issue tracker for this issue please point me to it so that I can vote for it.

    ===

    If WHMCS has an feature request/feature voting avenue to implement some type of account deletion queue per day... please point me to it and I'll make the request as well.

    ===

    Friday, June 22, 2012 9:54 AM
  • ===

    If WHMCS has an feature request/feature voting avenue to implement some type of account deletion queue per day... please point me to it and I'll make the request as well.

    ===

    I've sent support request for WHMCS dev team to add additional action hook (http://docs.whmcs.com/Hooks) for automation tasks because I don't see if there is one. If they will add it I can write some simple action hook which will move more than X account deletions to next day cron termination job.
    Friday, June 22, 2012 10:25 AM
  • ===

    If WHMCS has an feature request/feature voting avenue to implement some type of account deletion queue per day... please point me to it and I'll make the request as well.

    ===

    I've sent support request for WHMCS dev team to add additional action hook (http://docs.whmcs.com/Hooks) for automation tasks because I don't see if there is one. If they will add it I can write some simple action hook which will move more than X account deletions to next day cron termination job.
    Thank you, let us know how it goes and if there is anything I can do.
    Friday, June 22, 2012 12:36 PM
  • Hello,

    Sorry for the bit late response but:

    For the WSP work item: http://websitepanel.codeplex.com/workitem/274

    (this way both sides will have their issues resolved hopefuly :-))

    As far as IIS and MSSQL kind of db.. i agree WebIO.. thats a much better solution.. or even something like Apache where you can include other files to be loaded rather then everything in 1 big file will solve this issue :-)  though i wonder if Microsoft took "any big step" or simply continues with the 1 Big file tactic but maybe enhanced the capability of how it gets read or something :P (i think the last one.. improvement is much more likely.. that's why i wonder if what they did really has such a big impact as they say it should have.. or not :-))

    Regards,

    Marco


    Key4ce - IT professionals: www.key4ce.eu

    Saturday, June 23, 2012 5:16 AM
    Moderator