Introduction
After implementing private and shared outProc sessions states, I'm receiving the following error. This is a Sitecore 8.1 Update 3 environment. We are using SOLR as our indexer. We are also utilizing EXM. I decided to implement this when a slew of errors in the Content Delivery servers were indicating locked Contact records by the cluster, even though all of the CD's are in the same Analytics.ClusterName
.
Error
Unable to serialize the session state. In 'StateServer' and 'SQLServer' mode, ASP.NET will serialize the session state objects, and as a result non-serializable objects or MarshalByRef objects are not permitted. The same restriction applies if similar serialization is done by the custom session state store in 'Custom' mode.
[SerializationException: Type 'Sitecore.ContentSearch.SearchTypes.SearchResultItem' in Assembly 'Sitecore.ContentSearch, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.]
System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type) +970
System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context) +306
System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo() +188 System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder) +250
System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder) +96
System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck) +710 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck) +208 System.Web.Util.AltSerialization.WriteValueToStream(Object value, BinaryWriter writer) +2262
Configuration Settings
Below are the configurations setup. This is a local environment. My environment is currently setup as a single instance, but with private and shared session state enabled. The intended production environment is a distributed environment.
Content Delivery Web.config
<sessionState mode="Custom" customProvider="mssql" cookieless="false" timeout="20" sessionIDManagerType="Sitecore.SessionManagement.ConditionalSessionIdManager">
<providers>
<add name="mongo" type="Sitecore.SessionProvider.MongoDB.MongoSessionStateProvider, Sitecore.SessionProvider.MongoDB" sessionType="Standard" connectionStringName="session" pollingInterval="2" compression="true" />
<add name="mssql" type="Sitecore.SessionProvider.Sql.SqlSessionStateProvider, Sitecore.SessionProvider.Sql" sessionType="private" connectionStringName="session" pollingInterval="2" compression="true" />
</providers>
</sessionState>
Content Delivery Sitecore.Analytics.Tracking.config
<sharedSessionState patch:source="Sitecore.Analytics.Tracking.config" defaultProvider="mssql">
<providers>
<clear/>
<add name="InProc" type="System.Web.SessionState.InProcSessionStateStore"/>
<add name="mssql" type="Sitecore.SessionProvider.Sql.SqlSessionStateProvider,Sitecore.SessionProvider.Sql" connectionStringName="session" pollingInterval="2" compression="true" sessionType="shared" patch:source="Client.config"/>
</providers>
<manager type="Sitecore.Analytics.Tracking.SharedSessionState.SharedSessionStateManager, Sitecore.Analytics">
<param desc="configuration" ref="tracking/sharedSessionState/config"/>
</manager>
<config type="Sitecore.Analytics.Tracking.SharedSessionState.SharedSessionStateConfig, Sitecore.Analytics">
<param desc="maxLockAge">5000</param>
<!--
If an item in session state is already locked, this parameter is the time in milliseconds that the system is idle before making another attempt to apply a lock.
-->
<param desc="timeoutBetweenLockAttempts">10</param>
</config>
</sharedSessionState>
Intended Environment Setup
- 1 Primary CM Server
- 1 Secondary CM Server / Processing
- 3 Content Delivery Servers, load balanced.
- Heavy use of Analytics and xDB Contact Records
Research Done
On Sitecore's Known Issues for Sitecore 8, there is a mention of what seems to be a similar issue. But they don't list a Public Reference Number.
A number of dialogs could not be opened on Content Management servers with out-of-process session-state configured. This happened because the pipeline arguments were not serialized correctly. This has been fixed to ensure that these dialogs function properly, however please note that other Sitecore functions (in an out-of-process session-state server configuration) may not be supported as a result of this fix.
Summary
This looks like a bug in the Sitecore Content Search DLL. Has anyone come across this? I can't imagine that no one else uses OutProc private / sharesession states in a distributed environment.
System.Web.Util.AltSerialization.WriteValueToStream
. That's ASP.NET internals, not ContentSearch.SearchResultItem
.HttpContext.Current.Session[key]
was being utilized to store aKeyValuePair<DateTime,List<IInterfaceObject>>
.IInterfaceObject
-- Anyways, I fixed it by chaging the storage of that item and not using session for it. Worked like a charm! EDIT: I'll type up an answer to show my solution once I get a moment.