Microsoft SharePoint 2010: Profile and Package Sandbox Code

Properly profiling and packaging solutions to run in a sandbox environment gives you greater control of resource usage and scalability.

V. Gnanasekaran

When you build an enterprise-grade Web solution based on SharePoint 2010, performance tuning and testing are an important part of the development cycle. If your solution includes a lot of custom code, then it’s not just important, it’s essential.

SharePoint gives you many customization options, such as Web parts, custom receivers, custom actions and so on. You also have options for different execution models to give you greater control of performance, security and high availability. A “sandbox solution” is one such execution model.

You can create a performance profile of the code blocks you build to execute in a sandbox environment using the Visual Studio 2010 standalone profiler. Another important factor that will affect performance and scalability of sandbox solutions is the way you package and deploy custom code blocks such as Web parts. You can package those components to leverage sandbox services running across multiple servers, especially in enterprise-grade server farms.

SharePoint 2010 has various tools to help you identify potential bottlenecks in your custom code by investigating the time taken for code execution; calls to external resources such as Web services, databases, database queries and number of times queries are fired; and so on. You can use the Developer Dashboard to understand the time different code blocks take to execute. You can also analyze execution time with Unified Logging Service (ULS) logs.

Certain Constraints

In the case of sandbox solutions, the Developer Dashboard won’t provide any usable information. Also, there won’t be any execution information about the sandbox solution available in the ULS log. Sandbox components aren’t allowed to log information into ULS logs. Because SharePoint 2010 doesn’t help you understand the behavior of custom code blocks in a sandbox environment, you have to depend on the profiling capabilities of Visual Studio Team System2010.

When it comes to code profiling, you basically have two options: performance testing the project templates in Visual Studio 2010, or using a Visual Studio Team System standalone profiler. If you’re performance testing the Visual Studio project templates, you should set up your source code with all the required dependencies in the same machine where Visual Studio Team System (VSTS) 20 Ultimate Edition is installed. You’ll only be able to use this in the development environment. Keep in mind that it doesn’t capture details related to the code execution in a sandbox environment, nor does it work with the Host Header site collections.

If you’re using a Visual Studio Team System standalone profiler, you won’t need the source code. It works with compiled output. You can use it in upstream environments—such as stage, User Acceptance Testing (UAT), near-production and so on—where installing development tools isn’t permitted. This method also gives you some flexibility, so you can profile any processes apart from W3WP.exe. This helps you extract details related to code execution in a sandbox environment in terms of memory and execution time.

In the case of code blocks in a sandbox environment, the second option works well, as it gives you the flexibility to profile any process as required. In the case of a standalone profiler, you have two options:

  1. VSAspNetCmd.exe, which is meant for profiling W3WP.exe exclusively.
  2. VSPerfCmd.Exe, which you can use to profile any process.

The reports these profilers generate will give you more detailed information than the Developer Dashboard, including “tier” information. This is information about the call requests coming across machines and networks for external resources such as the database sandbox solution.

In the case of this sandbox solution, you can use two options: Executing the entire code in a sandbox process, or using a full-trust proxy (hybrid). Sometimes, to avoid the restrictions of the sandbox process, you should execute the code in a full-trust proxy. In either case, the code execution won’t happen in W3WP.exe, because that’s what happens in farm-based, out-of-the-box solutions and custom code. Hence, profiling W3WP.exe won’t yield any results for the sandbox code blocks.

Based on the option you choose, code execution for the sandbox solution will happen either in SPUCWorkerProcess.exe or SPUCWorkerProcessProxy.exe. In order to profile code execution and understand code behavior, these two processes are profiled based on the chosen model. In the case of a sandbox, you’ll profile SPUCWorkerProcess.exe. In the case of the hybrid approach using a full-trust proxy, you’ll profile SPUCWorkerProcessProxy.exe.

As “VSPerCMD.exe” is designed to profile any process required, you can use it to profile the SPUCWorkerProcess.exe and SPUCWorkerProcessProxy.exe processes. This will generate detailed information that will help you learn more about code execution in a sandbox environment in terms of memory and execution time.

Profiling Sandbox Code

When profiling sandbox code, you have two options: sampling and instrumentation. Sampling will give you details at a higher level. Instrumentation is preferred when you need in-depth analysis. Generally, sampling will suffice for common code-profiling requirements.

Here’s the sequence of commands needed to execute a profile. First, you need to set up the required environment variables:

VSPerfClrEnv /globalsampleon

Restart the machine, then use the following command:

VSPerfClrEnv /globalinteractionon

The command “globalsampleon” sets the profile to perform sampling. The command “globalinteractionon” lets the profiler collect the tier interaction information. After setting these environment variables, restart the machine.

The profiler isn’t consistent in providing tier information. So when tier information isn’t available, you need to set up these variables and restart the machine. That’s the natural behavior of the current version of the profiler.

In the next step after restarting the machine, set up the profiler with output file name and sampling.

Start the respective Web application. Identify the process ID of the respective process for that application—if multiple Web apps are running in that machine—then apply the following code:

VSPerfCmd /Start:Sample /Output:<FILE_NAME>.vsp /user:everyone /CrossSession

Next, based on the execution model you choose, identify “SPUCWorkerProcess.exe” or “SPUCWorkerProcessProxy.exe” and the profiler will attach to the chosen process:

VSPerfCmd /Attach:<PROCESS-ID>

Perform user actions of that Web app:

VSPerfCmd /Detach:<PROCESS-ID> VSPerfCmd /Shutdown

If you face issues related to symbols, then attach those symbols to the reports:

VSPerfReport.exe /summary:all /packsymbols <ReportName.VSP>

Finally, reset the environment variables:

vsperfclrenv /globaloff

You can open the reports this profiler generates in Visual Studio 2010 Ultimate edition to identify the “hot paths” and understand the code behavior in a sandbox environment. This will help in taking the appropriate corrective action to optimize performance.

Ensure that your Visual Studio environment is set up with the proper symbols to open the report without information loss. In the machines with standalone profilers installed along with any edition of Visual Studio 2010 (except Ultimate), you might encounter errors. It’s advisable to only install standalone profilers.

Solution Packaging

When it comes to packaging sandbox solutions, you must consider tier configurations. Tiers in sandbox solutions provide a way to group sandbox solutions based on resource requirements. By configuring tiers to run more processes, you can run more sandbox solutions concurrently within a farm. You can have a maximum of 20 worker processes across all the tiers on a single server.

The number of connections per process should be less than or equal to the number of application domains. That number of connections should also be less for the tier where the “ResourceMaxValue” property is set to a higher value.

You can only run one sandbox solution in each application domain at any time. The number of application domains represents the number of sandbox solutions you can load at any point. A single WSP file represents a sandbox solution. After uploading a WSP package, you can see it listed with the other sandbox solutions in the solution gallery.

You can configure sandbox solutions in either local mode or remote mode. You would use remote mode in scenarios where the farm has dedicated servers for sandbox code execution and for scalability.

So, if all the Web parts and custom code blocks are packaged as part of a single package, then that package will be loaded in one tier in an application domain. The other application domains remain in the same tier and won’t be used, so there won’t be any load distribution across tiers and servers. This could result in performance and scalability bottlenecks.

Sandbox code blocks packaged across multiple packages will result in multiple sandbox solutions. This provides the following benefits:

  1. Having multiple sandbox solutions helps improve resource monitoring. This helps you realize which sandbox solution is high in resource consumption. Then you can look for any chance to optimize the resource consumption for that particular sandbox solution. This also helps with tier planning. Having all the sandbox code blocks in a single solution or package won’t give you any details on the resource usage of particular Web parts or sandbox code blocks.
  2. You can make a tier configuration based on the average resource usage of the individual sandbox solutions, so it will result in proper utilization of the server resources.
  3. The deployment process will be easier. Individual Web parts and groups can be deployed or upgraded easily instead of deploying the whole solution to provide a minor update for a particular Web part.

Based on these factors, it’s better to logically group Web parts and other code blocks across multiple solution packages instead of packaging them all in a single sandbox solution. Proper sandbox code block packaging across different solution packages will help give you greater insight into resource usage for different sandbox code blocks.

Once you have a better view into resource utilization, you can use the profiling exercise to identify potential areas of improvement in the different parts of code blocks (in terms of performance) and to perform code-optimization activities. You can also improve performance, scalability and effective resource usage.

V. Gnanasekaran

V. Gnanasekaran has more than 14 years of experience as a TOGAF 9 Certified Enterprise Architect and part of Microsoft Consulting Services India, where he provides architectural consulting services to customers. His current areas of focus include SharePoint, SQL Server OLAP/OLTP and Windows Azure. He has published technology articles in various journals including The Architecture Journal and CodeProject. He blogs at gnanasekaran.com.