If you are going to deploy to a load balanced environment, a big plus is being able to develop in one. Unfortunately a lot of us don’t have that luxury! Here are some key points to help out.
Always rely on SharePoint’s central store – the database. Don’t try and store data on the file system as you will never be sure which server has what copy. Use lists for data that should be exposed to administrators and users. Use SPPersistedObject or the patterns & practices Application Setting Manager for application configuration.
This is just another method of storing state, albeit one that’s faster (yet limited in resources)! Be aware when using ASP.NET caching that every server will cache your data separately in its own copy of RAM. These will get out of sync resulting in inconsistencies that you will need to handle. You may find AppFabric Caching as described by Wictor Wilén a good solution to this problem.
Never store rich objects that aren’t thread safe such as SPListItem in the cache or any other form of state. Aside from potentially taking up unnecessary space, these objects won’t work properly once deserialized. Introducing caching also opens up your application to potential threading issues, as explained in “Understanding the Potential Pitfalls of Thread Synchronization” in this best practices article. You don’t need to use System.Threading to be multithreading!
Even if you can’t develop in a load balanced environment, it really pays to test in one. A lot of situations just can’t be reproduced otherwise! I strongly recommend to ensure your production environment always closely matches test in configuration (even if number of servers is unreasonable).
In summary: always store data in the database to avoid problems with different servers accessing the same content and keep any caching simple and stateless. Oh, and be sure to thoroughly test!
Do you ever find that your solution files have been “successfully deployed” according to SharePoint, yet the updated code isn’t taking effect? Perhaps you are trying to debug but breakpoints aren’t being hit when normally there’s no problem. Yet for some reason rebooting the server fixes the problem…
If that’s the case, the reason is probably file locking, most likely to occur if you have assemblies that need to be deployed to the Global Assembly Cache (GAC). If you ever find yourself in this situation, download a copy of the excellent Process Explorer tool, and follow these steps to verify:
- Start Process Explorer on the server affected.
- Press Ctrl+F, or in the menu click Find, Find Handle or DLL…, or just click the binoculars icon on the toolbar:
- Type the name of the assembly DLL and click Search.
- Under the Handle or DLL column, look for any assemblies located in the path C:\WINDOWS\assembly\temp. These lines tell you what process is locking the assembly.
OWSTIMER.EXE is the culprit!
The C:\WINDOWS\assembly\temp folder is Windows’ equivalent of “assembly purgatory” where the assembly will sit until Windows can deploy it. If the currently deployed assembly cannot be overwritten as it is already locked by a process then the DLL will stay there until the process releases the lock or ends, or until Windows is restarted (also ending the process).
One example where this problem can occur is when a WSP solution containing custom e-mail event receivers is upgraded. The timer service, OWSTIMER.EXE, executes event receivers via the Windows SharePoint Services Incoming E-Mail job. As the OWSTIMER.EXE process isn’t restarted when a solution is deployed, it will always hold onto the lock for the DLL containing the event receivers. The solution is to restart the Windows SharePoint Services Timer service on each web front end server. If you’re finding this problem in development, WSPBuilder v1.06 adds a “Recycle the Windows SharePoint Services Timer” option.
This problem can also occur when using Visual Studio if certain combinations of add-ins are installed. You can again check this by using Process Explorer and verify if DEVENV.EXE is the locking process. If so, take a good look at the add-ins you actually need. Regularly restarting Visual Studio is very frustrating and will severely cut your productivity!