Using Execution Tiers to Protect Well-Behaved Sandboxed Solutions
Published: April 2011
This topic explains how to use execution tiers to segregate resource-hungry or unstable sandboxed solutions into their own sandboxed worker process. This practice ensures that if one of these sandboxed solutions kills the process by exceeding an absolute resource limitation (as described in Resource Usage Limits on Sandboxed Solutions in SharePoint 2010), better behaved sandboxed solutions that are running in a different process are not affected.
As explained in Sandboxed Solutions Architecture in SharePoint 2010, on every server on which the SharePoint Foundation Sandboxed Code Service is running, there is a sandboxed worker process in which sandboxed solutions are executed. Each sandboxed solution runs in its own application domain, which is reused whenever the solution is invoked. If a sandboxed solution exceeds one of the absolute limits put on server resources, the process and all the sandboxed solutions that are running in it are terminated. This means that even the well-behaved solutions that are running in the process are terminated. For more information about this system, see Resource Usage Limits on Sandboxed Solutions in SharePoint 2010.
For every sandboxed worker process, there is a paired sandboxed worker proxy process that runs in full-trust. For simplicity's sake, the proxy process is not mentioned elsewhere in this topic, but be aware that every sandboxed worker process in every tier has its own proxy process partner. For more information about the proxy process, see Sandboxed Solutions Architecture in SharePoint 2010.
The Microsoft SharePoint Foundation object model lets you segregate sandboxed solutions into separate worker processes based on the amount of resources that they consumed the previous day. Every sandboxed worker process belongs to a group of one or more such processes called a tier. By default, there is only one tier. But you can create additional tiers and configure them so that sandboxed solutions whose resource use the previous day was under a certain threshold are processed in one tier, while more resource-hungry solutions are processed in another.
An execution tier is represented by the SPUserCodeExecutionTier class. Each execution tier is distinguished from the other tiers by four properties:
MaximumWorkerProcesses : This property represents the maximum number of sandboxed worker processes that can run in the tier. The default is 1. Setting this property to more than 1 causes an additional sandboxed worker process to be created (on the server that is handling the request) in the following circumstances: No existing sandboxed worker process in the tier has an application domain that is assigned to the sandboxed solution, and all existing sandboxed worker processes in the tier have reached their maximum level of application domains.
MaximumAppDomainsPerProcess : This property represents the maximum number of application domains that can run in a sandboxed worker process in the tier. The default is 10.
MaximumConnectionsPerProcess : This property represents the maximum number of allowed connections from a Microsoft ASP.NET worker process (w3wp.exe) to a sandboxed worker process in the tier. The default is 1.
ResourceMaxValue : This property, a Double that is usually between 0 and 1, determines which sandboxed solutions will run in the tier. The default is 0, and it must be set to a larger value or the tier is never used.
The ResourceMaxValue property is the most important. The SharePoint sandboxed solution monitoring infrastructure keeps a running total of how many times a sandboxed solution is executed. It also keeps a cumulative total of how many resource points the solution is earning. At the end of each day, these totals are recorded in the configuration database, and the accumulators are reset to zero. When a request for a sandboxed solution is received, the sandboxed solution execution manager uses these two values to compute the solution's average resource points earned per execution the previous day. The execution manager then examines the tier that has the lowest ResourceMaxValue value. If the solution's average is less than or equal to this value, the solution is executed in that tier. If the solution's average is larger, the execution manager compares it with the tier that has the next larger ResourceMaxValue value. If the solution's average from the previous day is larger than the ResourceMaxValue of any tier, it is not executed. The one tier that is created when SharePoint Foundation is installed has its ResourceMaxValue property set to the highest possible signed 32-bit integer: 2147483647. This very high value basically ensures that every sandboxed solution is executed.
The effect of this system is that when there is more than one tier, the relatively more resource-hungry sandboxed solutions, and therefore the sandboxed solutions that are most likely to exceed an absolute resource limit and thereby kill the process in which they are running, run in a different tier (and therefore a different process) from the tier in which the less resource-intensive sandboxed solutions are running.
By default, there is only one tier, and because it has only one sandboxed worker process (per server) by default, all sandboxed solutions that run on a specific server run in the same process. Therefore, to take advantage of the potential for process isolation that the tiering system can provide, you must create one or more additional tiers. You cannot do this in the user interface of Central Administration or SharePoint Foundation. It can only be done by using the object model (which can be accessed from SharePoint Management Shell). The following are the two necessary tasks for creating a tier:
Add a tier to the tiers collection of the SharePoint Foundation Sandboxed Code Service.
Set the ResourceMaxValue property of the tier to a value larger than zero.
The following code is an example.
SPUserCodeService ucHostService = SPUserCodeService.Local; SPUserCodeExecutionTier newTier = ucHostService.Tiers.Add("Well-Behaved Solutions"); newTier.ResourceMaxValue = 0.025; newTier.Update();
On most SharePoint farms, you should set the ResourceMaxValue property to a very small fraction of 1. What this property does, in effect, is define what constitutes a well-behaved sandboxed solution. Specifically, it defines how many resource points a well-behaved sandboxed solution should consume, on average, each time it is executed. To decide on the proper level, consider the following points:
It is clear that in most situations, the amount of resource points that are consumed by any one execution of a sandboxed solution must be very low. Unless the resource point quota is raised substantially above 300, even a sandboxed solution that uses just a single whole resource point in each execution could not be considered well-behaved.
SPUserCodeService ucHostService = SPUserCodeService.Local; SPUserCodeExecutionTier oldTier = ucHostService.Tiers["Well-Behaved Solutions"]; ucHostService.Tiers.Remove(new Guid(oldTier.Id.ToString()));
If you want to ensure that every sandboxed solution can execute, make sure that there is always at least one tier whose ResourceMaxValue property is set to MaxValue. Because this is the highest value to which a site collection's daily resource quota can be set, any sandboxed solution that exceeds this on a single execution immediately exhausts the resource point quota and blocks any further execution of sandboxed solutions on that site collection for the remainder of the day. Hence, no sandboxed solution could have an average per execution resource usage level higher than MaxValue. (As a practical matter, in any realistic scenario, setting ResourceMaxValue to 2147483647 would be high enough to make sure that even the most resource-hungry sandboxed solution would fit the tier. This is the default value of the ResourceMaxValue property for the one tier that is created when SharePoint is installed.
The value of the Name and DisplayName properties of the default tier that is created when SharePoint Foundation is installed is the empty string.