SharePoint 2010: to RBS or not to RBS

… that’s the question.

Joel Olsen recently wrote a blog post about the pros and cons of using Remote Blob Storage (RBS) (formerly know as External Blob Storage – EBS). This post also contains a bunch of links to various resources from Microsoft and other vendors of RBS technology.

The bottom line is, that using RBS can greatly improve performance when working with large documents in SharePoint, while the actual data-size is much lower than storing those documents in the SharePoint content-database.

On the other side RBS is would be the wrong choice, when mostly small documents or listdata is stored in SharePoint, because in this case the overhead of moving the data out of SQL-server and into the filestream is too costly. Back in 2006 Microsoft already published a paper called “To BLOB or Not To BLOB: Large Object Storage in a Database or a Filesystem”, which concludes that files smaller than 256 KB would be best stored in the database, while files larger than 1 MB are most efficiently sored in the filesystem. Everything in between “depends”.

Restart of application pools revised (Windows 2008)

Up to Windows 2008 there was a nifty little VB-Script called iisapp.vbs. This allowed to just restart the application pool without having to restart the whole IIS. For one this is much faster and also this doesn’t effect other application pool. Thus you can restart a single application.

But with Windows 2008 this script is no longer provided. But fortunatly there is a new kid in town: appcmd.exe. This tool can be found in c:\windows\system32\inetsrv.

To restart (recylce) an application pool you just call:

c:\Windows\System32\inetsrv\appcmd recycle apppool "SharePoint - 80"

Restart of an application pool instead of IIS

Once in a while you have to deploy assemblies for a SharePoint based solution (ok, you also might have other solutions which need Assemblies Smiley, but in my case I just stumbled across a SharePoint based solution). But deploying the assembly to the GAC or the local bin folder does not mean, that SharePoint (or the IIS) automatically pick up this new version of the Assembly.

Usually you’ll issue an iisreset command in order to get IIS to reload all needed assemblies. Unfortunatly this does take some time, until IIS is fully restarted. This is especially true, when more than one application-pool is running within IIS (for e.g. central administration as well as a couple of web-applications).

Actually it would be sufficient just to restart the portal web-application instead of the whole IIS. So this would mean, we only restart the application pool. Actually this is quite easy to do. Using iisapp.vbs this is just a matter of

cscript iisapp.vbs /a "SharePoint - 80" /r

Actually this could also be part of a nant-build script, so that with each build the application pool is being restart.

<?xml version="1.0" encoding="utf-8" ?>
<project name="Solution" default="deploy" xmlns="http://nant.sf.net/schemas/nant.xsd">
  <loadtasks assembly="f:\build-tools\nantcontrib\bin\nant.contrib.tasks.dll"/>
  <target name="build">
    <msbuild project="FirstActivity.csproj"/>
  </target>
  <target name="deploy" depends="build">
    <gac-install >
      <assemblies>
        <include name="bin\Debug\FirstActivity.dll"/>
      </assemblies>
    </gac-install>
    <exec program="cscript" commandline="iisapp.vbs" workingdir="c:\windows\system32" verbose="true">
      <arg value="/a &quot;SharePoint - 80&quot;" />
      <arg value="/r"/>
    </exec>
  </target>
</project>

Exponention in c#

To compute 10 to the power 2 shouldn’t be any problem

int result = 10 ^ 2;

As if! Visual Studio strongly believes that the result of this computation should be 8. Damn! ^ is a reserved symbol in c# for bitwise exclusive or (XOR). The correct way to computer this would be

int result = Math.Pow(10, 2);

Logging in NHibernat 3.0

With the release of NHibernate 3.0 the way NHibernate handles logging is changed. Up to 2.1.2 NHibernate used log4net exclusive for logging. The usage of log4net was directly tied into each class of NHibernate.

Now this has been decoupled. NHibernate 3.0 introduces a LoggingProvider. So instead of

private static readonly ILog log = LogManager.GetLogger(typeof (Loader));

a new logger is created using

private static readonly IInternalLogger log = LoggerProvider.LoggerFor(typeof (Loader));

Even though this might not seem like a big deal, there is more to the LoggingProvider. The logging provider currently only supports log4net (well, and a NoLoggingLoggerFactory). In order to determine whether log4net is available for logging, the LoggingProvider looks in the current SearchPath of BaseDirectory of the AppDomain like this:

// look for log4net.dll
string baseDir = AppDomain.CurrentDomain.BaseDirectory;
string relativeSearchPath = AppDomain.CurrentDomain.RelativeSearchPath;
string binPath = relativeSearchPath == null ? baseDir : Path.Combine(baseDir, relativeSearchPath);
var log4NetDllPath = Path.Combine(binPath, "log4net.dll");

What go me started was the fact, the my log4net configuration wasn’t creating any log-output, and I was extremely puzzled on why. I checked my config a dozen times without any error. This was working perfectly fine when working with NHibernate 2.1.2.

After looking at the LoggingProvider and the way logging is initialized it struck me: my log4net assembly is located in the GAC – the the lookup for log4net isn’t detecting my log4net assembly! Changing the properties of the reference to log4net to Copy Local resolved this issue.

Supressing Messages from FXCop

In a recent project I rellay nailed the code using FXCop. The goal was to eliminate all messages of FXCop.

After a short periode of time I already figure: no way! There are just a couple of cases, where I have to irgnore the messages of FXCop. Luckily there is an easy way to supress the messages of FXCop. Just open the context menu of the message and copy the message as SupresseMessage to the clipboard.

suppress_messages

Next you can insert that at the appropriate position within your code, most likely as a method-attribute.

[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes")]

OK, so now your’re good to go. The next run of FXCop should present you a lot less messages.

And if not? Something went wrong. Some little, very well hidden comment in the documentations says:

The ConditionalAttribute is applied to this class, specifying the preprocessing symbol “CODE_ANALYSIS” as the conditional symbol that determines whether the attribute call is included or omitted. If the symbol is defined, the attribute call is included; otherwise, the call is omitted.

OK. So opening up the project properties and adding the symbol CODE_ANALYSIS helped a lot in getting the number of FXCop messages down.