I've been fighthing for long with an issue we have on a quite big installation (75+ portals, 6500+ pages, 11000+ modules).
The issue only manifested when installing some modules and it would cause the application to die because of a timeout, so we were unable to install any new modules.
The problem turned out to be in the way the installer process the .dnn file and how it updates the module information.
Basically it went that way:
- Register the DesktopModules
- Register any ModuleDefintions for the modules
- Register all the ModuleControls for all definitions
So in a medium-large module this could be like 4-5 modules, 10-12 moduledefinitions, and 30-40 controls.
The problem is that in each of these updates the system did a clear on the host cache. So all the information that DNN uses to cache was cleared after each of these updates (so around 50 times). That caused that the same information was read again from the db after each call causing at the end the timeout.
The issue with this problem is that it would only appear in big sites and when installing big modules. This it's like and exponential issue: the bigger the site and the bigger the module the easier you'll get this error.
We changed the code so next version will include the fix for this but in the meantime you can patch your DNN installations by doing this easy fix (this applies to any DNN version up and including 4.8). To solve this issue you'll have to open the DotNetNuke solution in VS.NET and recompile the DotNetNuke.dll:
In PaDnnInstallerBase.vb, look for method:
Protected Overridable Sub RegisterModules(ByVal Folder As PaFolder, ByVal Modules As ArrayList, ByVal Controls As ArrayList)
change the following calls:
objDesktopModules.UpdateDesktopModule(objDesktopModule)
objModuleDefinitons.UpdateModuleDefinition(objModuleDefinition)
ModuleControlController.UpdateModuleControl(objModuleControl)
to:
objDesktopModules.UpdateDesktopModule(objDesktopModule, False)
objModuleDefinitons.UpdateModuleDefinition(objModuleDefinition, False)
ModuleControlController.UpdateModuleControl(objModuleControl, False)
and just before this line, at the end of the method code:
InstallerInfo.Log.EndJob(REGISTER_End)
add
DataCache.ClearHostCache(True)
In DesktopModuleController.vb change:
Public Sub UpdateDesktopModule(ByVal objDesktopModule As DesktopModuleInfo)
DataProvider.Instance().UpdateDesktopModule(objDesktopModule.DesktopModuleID, objDesktopModule.ModuleName, objDesktopModule.FolderName, objDesktopModule.FriendlyName, objDesktopModule.Description, objDesktopModule.Version, objDesktopModule.IsPremium, objDesktopModule.IsAdmin, objDesktopModule.BusinessControllerClass, objDesktopModule.SupportedFeatures, objDesktopModule.CompatibleVersions, objDesktopModule.Dependencies, objDesktopModule.Permissions)
DataCache.ClearHostCache(True)
End Sub
to:
Public Sub UpdateDesktopModule(ByVal objDesktopModule As DesktopModuleInfo)
UpdateDesktopModule(objDesktopModule, True)
End Sub
Friend Sub UpdateDesktopModule(ByVal objDesktopModule As DesktopModuleInfo, ByVal clearCache As Boolean)
DataProvider.Instance().UpdateDesktopModule(objDesktopModule.DesktopModuleID, objDesktopModule.ModuleName, objDesktopModule.FolderName, objDesktopModule.FriendlyName, objDesktopModule.Description, objDesktopModule.Version, objDesktopModule.IsPremium, objDesktopModule.IsAdmin, objDesktopModule.BusinessControllerClass, objDesktopModule.SupportedFeatures, objDesktopModule.CompatibleVersions, objDesktopModule.Dependencies, objDesktopModule.Permissions)
If clearCache Then DataCache.ClearHostCache(True)
End Sub
In ModuleDefinitionController.vb change:
Public Sub UpdateModuleDefinition(ByVal objModuleDefinition As ModuleDefinitionInfo)
DataProvider.Instance().UpdateModuleDefinition(objModuleDefinition.ModuleDefID, objModuleDefinition.FriendlyName, objModuleDefinition.DefaultCacheTime)
DataCache.ClearHostCache(True)
End Sub
to:
Public Sub UpdateModuleDefinition(ByVal objModuleDefinition As ModuleDefinitionInfo)
UpdateModuleDefinition(objModuleDefinition, True)
End Sub
Public Sub UpdateModuleDefinition(ByVal objModuleDefinition As ModuleDefinitionInfo, ByVal clearCache As Boolean)
DataProvider.Instance().UpdateModuleDefinition(objModuleDefinition.ModuleDefID, objModuleDefinition.FriendlyName, objModuleDefinition.DefaultCacheTime)
If clearCache Then DataCache.ClearHostCache(True)
End Sub
And finally in ModuleControlController.vb change:
Public Shared Sub UpdateModuleControl(ByVal objModuleControl As ModuleControlInfo)
provider.UpdateModuleControl(objModuleControl.ModuleControlID, objModuleControl.ModuleDefID, objModuleControl.ControlKey, objModuleControl.ControlTitle, objModuleControl.ControlSrc, objModuleControl.IconFile, CType(objModuleControl.ControlType, Integer), objModuleControl.ViewOrder, objModuleControl.HelpURL, objModuleControl.SupportsPartialRendering)
DataCache.ClearHostCache(True)
End Sub
to:
Public Shared Sub UpdateModuleControl(ByVal objModuleControl As ModuleControlInfo)
UpdateModuleControl(objModuleControl, True)
End Sub
Public Shared Sub UpdateModuleControl(ByVal objModuleControl As ModuleControlInfo, ByVal clearCache As Boolean)
provider.UpdateModuleControl(objModuleControl.ModuleControlID, objModuleControl.ModuleDefID, objModuleControl.ControlKey, objModuleControl.ControlTitle, objModuleControl.ControlSrc, objModuleControl.IconFile, CType(objModuleControl.ControlType, Integer), objModuleControl.ViewOrder, objModuleControl.HelpURL, objModuleControl.SupportsPartialRendering)
If clearCache Then DataCache.ClearHostCache(True)
End Sub
now recompile and just copy DotNetNuke.dll to your DNN installation.
As always remember to make a copy of your files before doing any upgrade and try it on a testing site.
Conclusion:
Caching is a very important thing since it can save your application from the most expensive db calls (and in DNN we have quite a few of those).
But it's also very important to understand how it is used and check that your code is working fine in different situations.