Skip to content

Thread-safe Item Collections for Concurrent mode #112

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Mar 21, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -611,7 +611,7 @@ public override SessionStateStoreData CreateNewStoreData(HttpContextBase context
staticObjects = GetSessionStaticObjects(context.ApplicationInstance.Context);
}

return new SessionStateStoreData(new SessionStateItemCollection(), staticObjects, timeout);
return new SessionStateStoreData(CreateItemCollection(), staticObjects, timeout);
}

/// <inheritdoc />
@@ -628,7 +628,7 @@ public override async Task CreateUninitializedItemAsync(

string encodedBuf;

var item = new SessionStateStoreData(new SessionStateItemCollection(),
var item = new SessionStateStoreData(CreateItemCollection(),
GetSessionStaticObjects(context.ApplicationInstance.Context),
timeout);

@@ -1038,6 +1038,28 @@ private static string GetEncodedStringFromMemoryStream(MemoryStream s)
return Convert.ToBase64String(bytes.Array, bytes.Offset, bytes.Count);
}

private static ISessionStateItemCollection CreateItemCollection()
{
return SessionStateModuleAsync.AllowConcurrentRequestsPerSession ?
new ConcurrentSessionStateItemCollection() as ISessionStateItemCollection :
new SessionStateItemCollection() as ISessionStateItemCollection;
}

private static void SerializeItemCollection(ISessionStateItemCollection items, BinaryWriter writer)
{
if (items is ConcurrentSessionStateItemCollection concurrentItems)
concurrentItems.Serialize(writer);
else if (items is SessionStateItemCollection defaultItems)
defaultItems.Serialize(writer);
}

private static ISessionStateItemCollection DeserializeItemCollection(BinaryReader reader)
{
return SessionStateModuleAsync.AllowConcurrentRequestsPerSession ?
ConcurrentSessionStateItemCollection.Deserialize(reader) as ISessionStateItemCollection :
SessionStateItemCollection.Deserialize(reader) as ISessionStateItemCollection;
}

private static void Serialize(SessionStateStoreData item, Stream stream)
{
bool hasItems = true;
@@ -1060,7 +1082,7 @@ private static void Serialize(SessionStateStoreData item, Stream stream)

if (hasItems)
{
((SessionStateItemCollection)item.Items).Serialize(writer);
SerializeItemCollection(item.Items, writer);
}

if (hasStaticObjects)
@@ -1089,7 +1111,7 @@ internal static SessionStateStoreData DeserializeStoreData(HttpContextBase conte
private static SessionStateStoreData Deserialize(HttpContextBase context, Stream stream)
{
int timeout;
SessionStateItemCollection sessionItems;
ISessionStateItemCollection sessionItems;
bool hasItems;
bool hasStaticObjects;
HttpStaticObjectsCollection staticObjects;
@@ -1106,11 +1128,11 @@ private static SessionStateStoreData Deserialize(HttpContextBase context, Stream

if (hasItems)
{
sessionItems = SessionStateItemCollection.Deserialize(reader);
sessionItems = DeserializeItemCollection(reader);
}
else
{
sessionItems = new SessionStateItemCollection();
sessionItems = CreateItemCollection();
}

if (hasStaticObjects)
9 changes: 8 additions & 1 deletion src/SessionStateModule/InProcSessionStateStoreAsync.cs
Original file line number Diff line number Diff line change
@@ -437,7 +437,14 @@ private SessionStateStoreData CreateLegitStoreData(
{
if (sessionItems == null)
{
sessionItems = new SessionStateItemCollection();
if (SessionStateModuleAsync.AllowConcurrentRequestsPerSession)
{
sessionItems = new ConcurrentNonSerializingSessionStateItemCollection();
}
else
{
sessionItems = new SessionStateItemCollection();
}
}

if (staticObjects == null && context != null)
Original file line number Diff line number Diff line change
@@ -66,8 +66,10 @@
</Compile>
<Compile Include="SessionEventSource.cs" />
<Compile Include="SessionOnEndTarget.cs" />
<Compile Include="SessionStateItemCollections.cs" />
<Compile Include="SessionStateModuleAsync.cs" />
<Compile Include="SessionStateStoreProviderAsyncBase.cs" />
<Compile Include="StateSerializationUtil.cs" />
<Compile Include="TaskAsyncHelper.cs" />
</ItemGroup>
<ItemGroup>
18 changes: 18 additions & 0 deletions src/SessionStateModule/Resources/SR.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions src/SessionStateModule/Resources/SR.resx
Original file line number Diff line number Diff line change
@@ -117,6 +117,9 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Cant_serialize_session_state" xml:space="preserve">
<value>Unable to serialize the session state. For out-of-proc session stores, ASP.NET will serialize the session state objects, and as a result non-serializable objects or MarshalByRef objects are not permitted.</value>
</data>
<data name="Error_Occured_Reading_Config_Secion" xml:space="preserve">
<value>Error occured when reading config secion '{0}'.</value>
</data>
@@ -126,6 +129,9 @@
<data name="Invalid_session_custom_provider" xml:space="preserve">
<value>The custom session state store provider name '{0}' is invalid.</value>
</data>
<data name="Invalid_session_state" xml:space="preserve">
<value>The session state information is invalid and might be corrupted.</value>
</data>
<data name="Missing_session_custom_provider" xml:space="preserve">
<value>The custom session state store provider '{0}' is not found.</value>
</data>
Loading