Be careful with setting the SessionTimeout system property to a value out of the [10, 2147483647] range (SSRS 2008 R2)

Most of the functionality implemented in the web service that requires getting the value of any system property doesn’t read it directly from the ReportServer Catalog. Instead, it uses a set of members from the Microsoft.ReportingServices.Library.Global class that ultimately expose those system properties.

The reason why it’s been made that way is because that class leverages a caching mechanism which lazily reads (as they are requested) the different system properties from the database only once or when a change to the values in the backend (via the supported API) invalidates this cache (CachedSystemProperties).

When the ReportingService2010.GetSystemProperties method of the Web Service is invoked, it always goes down to the Catalog in the back-end, to return the most current value set for each system property. The implementation of this API is the only one that doesn’t use the intermediate cache I mentioned above.

Calling that method is, for instance, what SSMS UI does in order to get the values it uses to populate the following grid:

image

Following is the managed stack of the thread that executes the GetSystemProperties method:

2207ebc0 2d085fc0 Microsoft.ReportingServices.Library.DBInterface.GetAllConfigurationInfo()<-- This method calls the GetAllConfigurationInfo stored procedure to retrieve all system properties.

2207ebc4 2d085c12 Microsoft.ReportingServices.Library.GetSystemPropertiesAction.PerformActionNow()

2207ebe4 2ce4fc58 Microsoft.ReportingServices.Library.RSSoapAction`1[[System.__Canon, mscorlib]].Execute()

2207ec44 2d085a7c Microsoft.ReportingServices.WebServer.ReportingService2010Impl.GetSystemProperties(Microsoft.ReportingServices.Library.Soap.Property[], Microsoft.ReportingServices.Library.Soap.Property[] ByRef)

2207ec70 2d085a05 Microsoft.ReportingServices.WebServer.ReportingService2010.GetSystemProperties(Microsoft.ReportingServices.Library.Soap.Property[], Microsoft.ReportingServices.Library.Soap.Property[] ByRef)

2207f0e0 6b231b4c [HelperMethodFrame_1OBJ: 2207f0e0] System.RuntimeMethodHandle._InvokeMethodFast(System.Object, System.Object[], System.SignatureStruct ByRef, System.Reflection.MethodAttributes, System.RuntimeTypeHandle)

2207f150 698d5618 System.RuntimeMethodHandle.InvokeMethodFast(System.Object, System.Object[], System.Signature, System.Reflection.MethodAttributes, System.RuntimeTypeHandle)

2207f1a0 698d53c6 System.Reflection.RuntimeMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo, Boolean)

2207f1dc 698d52ae System.Reflection.RuntimeMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo)

2207f1fc 6550917b System.Web.Services.Protocols.LogicalMethodInfo.Invoke(System.Object, System.Object[])

2207f220 65540a3e System.Web.Services.Protocols.WebServiceHandler.Invoke()

2207f260 65540715 System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()

2207f290 655410a7 System.Web.Services.Protocols.SyncSessionlessHandler.ProcessRequest(System.Web.HttpContext)

2207f2a4 20461296 System.Web.HttpApplication+CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()

2207f2d8 20433aac System.Web.HttpApplication.ExecuteStep(IExecutionStep, Boolean ByRef)

2207f318 2043f583 System.Web.HttpApplication+ApplicationStepManager.ResumeSteps(System.Exception)

2207f368 2043302c System.Web.HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest(System.Web.HttpContext, System.AsyncCallback, System.Object)

2207f384 2043659c System.Web.HttpRuntime.ProcessRequestInternal(System.Web.HttpWorkerRequest)

2207f3b8 20436243 System.Web.HttpRuntime.ProcessRequestNoDemand(System.Web.HttpWorkerRequest)

2207f3c8 20a0c297 System.Web.HttpRuntime.ProcessRequest(System.Web.HttpWorkerRequest)

2207f3dc 0470a4fb ReportingServicesHttpRuntime.RsHttpRuntime.ProcessRequest(Microsoft.ReportingServices.HostingInterfaces.IRsHttpPipeline)

Now, when the SetSystemProperties method is called (that is what SSMS UI calls when you change the value of any setting in the dialog above and click OK), it does two things:

1.- persists whatever array of values is passed into the Catalog

2fc5efb4 2d088538 Microsoft.ReportingServices.Library.DBInterface.SetConfigurationInfo(Microsoft.ReportingServices.Library.SystemProperties) <-- This method calls the SetConfigurationInfo stored procedure to persist the values of the system properties.

2fc5efb8 2d0877d3 Microsoft.ReportingServices.Library.SetSystemPropertiesAction.PerformActionNow()

2fc5efdc 2ce4fc58 Microsoft.ReportingServices.Library.RSSoapAction`1[[System.__Canon, mscorlib]].Execute()

2fc5f03c 2d0874ff Microsoft.ReportingServices.WebServer.ReportingService2010Impl.SetSystemProperties(Microsoft.ReportingServices.Library.Soap.Property[])

2fc5f064 2d087492 Microsoft.ReportingServices.WebServer.ReportingService2010.SetSystemProperties(Microsoft.ReportingServices.Library.Soap.Property[])

2fc5f4b4 6b231b4c [HelperMethodFrame_1OBJ: 2fc5f4b4] System.RuntimeMethodHandle._InvokeMethodFast(System.Object, System.Object[], System.SignatureStruct ByRef, System.Reflection.MethodAttributes, System.RuntimeTypeHandle)

2fc5f524 698d5618 System.RuntimeMethodHandle.InvokeMethodFast(System.Object, System.Object[], System.Signature, System.Reflection.MethodAttributes, System.RuntimeTypeHandle)

2fc5f574 698d53c6 System.Reflection.RuntimeMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo, Boolean)

2fc5f5b0 698d52ae System.Reflection.RuntimeMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo)

2fc5f5d0 6550917b System.Web.Services.Protocols.LogicalMethodInfo.Invoke(System.Object, System.Object[])

2fc5f5f4 65540a3e System.Web.Services.Protocols.WebServiceHandler.Invoke()

2fc5f634 65540715 System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()

2fc5f664 655410a7 System.Web.Services.Protocols.SyncSessionlessHandler.ProcessRequest(System.Web.HttpContext)

2fc5f678 20461296 System.Web.HttpApplication+CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()

2fc5f6ac 20433aac System.Web.HttpApplication.ExecuteStep(IExecutionStep, Boolean ByRef)

2fc5f6ec 2043f583 System.Web.HttpApplication+ApplicationStepManager.ResumeSteps(System.Exception)

2fc5f73c 2043302c System.Web.HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest(System.Web.HttpContext, System.AsyncCallback, System.Object)

2fc5f758 2043659c System.Web.HttpRuntime.ProcessRequestInternal(System.Web.HttpWorkerRequest)

2fc5f78c 20436243 System.Web.HttpRuntime.ProcessRequestNoDemand(System.Web.HttpWorkerRequest)

2fc5f79c 20a0c297 System.Web.HttpRuntime.ProcessRequest(System.Web.HttpWorkerRequest)

2fc5f7b0 0470a4fb ReportingServicesHttpRuntime.RsHttpRuntime.ProcessRequest(Microsoft.ReportingServices.HostingInterfaces.IRsHttpPipeline)

2.- and, invalidates the system properties cache (CachedSystemProperties) from where everything else reads them

2fc5efd0 2d0886a8 Microsoft.ReportingServices.Library.CachedSystemProperties.set_Cache(System.Collections.Hashtable) <-- This is setting Cache to null. Due to compiler optimizations, the frame for the InvalidateCache function doesn’t show up. Its implementation has been inlined into FinalizeAction.

2fc5efd4 2d088690 Microsoft.ReportingServices.Library.SetSystemPropertiesAction.FinalizeAction()

2fc5efd8 2ce4fd2f Microsoft.ReportingServices.Library.RSSoapAction`1[[System.__Canon, mscorlib]].Execute()

2fc5f03c 2d0874ff Microsoft.ReportingServices.WebServer.ReportingService2010Impl.SetSystemProperties(Microsoft.ReportingServices.Library.Soap.Property[])

2fc5f064 2d087492 Microsoft.ReportingServices.WebServer.ReportingService2010.SetSystemProperties(Microsoft.ReportingServices.Library.Soap.Property[])

2fc5f4b4 6b231b4c [HelperMethodFrame_1OBJ: 2fc5f4b4] System.RuntimeMethodHandle._InvokeMethodFast(System.Object, System.Object[], System.SignatureStruct ByRef, System.Reflection.MethodAttributes, System.RuntimeTypeHandle)

2fc5f524 698d5618 System.RuntimeMethodHandle.InvokeMethodFast(System.Object, System.Object[], System.Signature, System.Reflection.MethodAttributes, System.RuntimeTypeHandle)

2fc5f574 698d53c6 System.Reflection.RuntimeMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo, Boolean)

2fc5f5b0 698d52ae System.Reflection.RuntimeMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo)

2fc5f5d0 6550917b System.Web.Services.Protocols.LogicalMethodInfo.Invoke(System.Object, System.Object[])

2fc5f5f4 65540a3e System.Web.Services.Protocols.WebServiceHandler.Invoke()

2fc5f634 65540715 System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()

2fc5f664 655410a7 System.Web.Services.Protocols.SyncSessionlessHandler.ProcessRequest(System.Web.HttpContext)

2fc5f678 20461296 System.Web.HttpApplication+CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()

2fc5f6ac 20433aac System.Web.HttpApplication.ExecuteStep(IExecutionStep, Boolean ByRef)

2fc5f6ec 2043f583 System.Web.HttpApplication+ApplicationStepManager.ResumeSteps(System.Exception)

2fc5f73c 2043302c System.Web.HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest(System.Web.HttpContext, System.AsyncCallback, System.Object)

2fc5f758 2043659c System.Web.HttpRuntime.ProcessRequestInternal(System.Web.HttpWorkerRequest)

2fc5f78c 20436243 System.Web.HttpRuntime.ProcessRequestNoDemand(System.Web.HttpWorkerRequest)

2fc5f79c 20a0c297 System.Web.HttpRuntime.ProcessRequest(System.Web.HttpWorkerRequest)

2fc5f7b0 0470a4fb ReportingServicesHttpRuntime.RsHttpRuntime.ProcessRequest(Microsoft.ReportingServices.HostingInterfaces.IRsHttpPipeline)

Now if, for example, someone calls ReportExecutionService.LoadReport2, that function creates a new session action object (CreateNewSessionAction) where the session timeout is stored (the one defined in the SessionTimeout system property.) However, as I said before it uses the Microsoft.ReportingServices.Library.Global.SessionTimeoutSeconds property which relies on that cache that could, eventually, query the database to retrieve the value of that specific property, assuming it wasn’t cached already. The value retrieved from that cache is wrapped around a utility class that provides storage and functionality to persist not only the value but the units in which it is expressed, or the range of valid values to which the system property is expected to conform. With that, when you try to get the value stored in that wrapper class, it goes through a validation process that may decide, for instance, that because the value stored in the system property is out of the range of expected values, it will give you back a default value which was specified when the instance of the wrapper class was instantiated.

Following is the stack of the thread when it goes through that validation for the SessionTimeout system property:

2fc5ef00 24e2988e Microsoft.ReportingServices.Diagnostics.RangedParameter`1[[System.Int32, mscorlib]].Validate(System.String, System.Object ByRef)

2fc5ef20 2ceb6143 Microsoft.ReportingServices.Diagnostics.ApplicationParameter.InterpretValue()

2fc5ef58 2ceb5ff7 Microsoft.ReportingServices.Diagnostics.ApplicationParameter.get_BaseValue()

2fc5ef68 2d08fb21 Microsoft.ReportingServices.Diagnostics.RangedParameter`1[[System.Int32, mscorlib]].get_Value()

2fc5ef74 24e29783 Microsoft.ReportingServices.Library.Global.get_SessionTimeoutSeconds()

2fc5ef88 24e24ecf Microsoft.ReportingServices.Library.CreateNewSessionAction.Save()

2fc5eff4 24e23b53 Microsoft.ReportingServices.WebServer.ReportExecution2005Impl.LoadReport(System.String, System.String, Microsoft.ReportingServices.Library.Soap2005.ExecutionInfo2 ByRef)

2fc5f038 24e239cb Microsoft.ReportingServices.WebServer.ReportExecutionService.LoadReport2(System.String, System.String, Microsoft.ReportingServices.Library.Soap2005.ExecutionInfo2 ByRef)

2fc5f4b4 6b231b4c [HelperMethodFrame_1OBJ: 2fc5f4b4] System.RuntimeMethodHandle._InvokeMethodFast(System.Object, System.Object[], System.SignatureStruct ByRef, System.Reflection.MethodAttributes, System.RuntimeTypeHandle)

2fc5f524 698d5618 System.RuntimeMethodHandle.InvokeMethodFast(System.Object, System.Object[], System.Signature, System.Reflection.MethodAttributes, System.RuntimeTypeHandle)

2fc5f574 698d53c6 System.Reflection.RuntimeMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo, Boolean)

2fc5f5b0 698d52ae System.Reflection.RuntimeMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo)

2fc5f5d0 6550917b System.Web.Services.Protocols.LogicalMethodInfo.Invoke(System.Object, System.Object[])

2fc5f5f4 65540a3e System.Web.Services.Protocols.WebServiceHandler.Invoke()

2fc5f634 65540715 System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()

2fc5f664 655410a7 System.Web.Services.Protocols.SyncSessionlessHandler.ProcessRequest(System.Web.HttpContext)

2fc5f678 20461296 System.Web.HttpApplication+CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()

2fc5f6ac 20433aac System.Web.HttpApplication.ExecuteStep(IExecutionStep, Boolean ByRef)

2fc5f6ec 2043f583 System.Web.HttpApplication+ApplicationStepManager.ResumeSteps(System.Exception)

2fc5f73c 2043302c System.Web.HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest(System.Web.HttpContext, System.AsyncCallback, System.Object)

2fc5f758 2043659c System.Web.HttpRuntime.ProcessRequestInternal(System.Web.HttpWorkerRequest)

2fc5f78c 20436243 System.Web.HttpRuntime.ProcessRequestNoDemand(System.Web.HttpWorkerRequest)

2fc5f79c 20a0c297 System.Web.HttpRuntime.ProcessRequest(System.Web.HttpWorkerRequest)

2fc5f7b0 0470a4fb ReportingServicesHttpRuntime.RsHttpRuntime.ProcessRequest(Microsoft.ReportingServices.HostingInterfaces.IRsHttpPipeline)

In the case of the SessionTimeout system property, it means that if you specify a value out of the range [10, Int32.MaxValue], like the 5 used in this example, it returns a 600 (which is hardcoded, m_DefaultSessionTimeoutSeconds), and if your tracing level is at minimum TraceWarning, you see the following entries in your SSRS log file:

library!ReportServer_0-8!2fc0!07/08/2012-23:34:29:: Value '5' of parameter 5 is out of the range [10, 2147483647].

library!ReportServer_0-8!2fc0!07/08/2012-23:34:29:: w WARN: Initializing SessionTimeout to default value of '600' second(s) because it was incorrectly specified in Server system properties as '5'.

The information is enough to understand that the system property SessionTimeout was set to an invalid value and that it has decided to use a default instead.

The problem is that, if you happen to make that mistake in a very busy server, by the time you realize you made that mistake, the disks were SSRS keeps the LogFiles may be full with hundreds of thousands of these messages.

I’ll propose a couple of improvements in this area to the product group. Meanwhile, just take it into consideration and don’t set it out of that range.