Skip to content

Commit 2a591ef

Browse files
Add 'skipKeepAliveWhenUnused' to reduce unneeded traffic with session state stores. (#80)
1 parent 452ad61 commit 2a591ef

File tree

7 files changed

+52
-13
lines changed

7 files changed

+52
-13
lines changed

Readme.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Information on contributing to this repo is in the [Contributing Guide](CONTRIBU
2424
```xml
2525
<sessionState cookieless="false" regenerateExpiredSessionId="true" mode="Custom" customProvider="YourProviderName">
2626
<providers>
27-
<add name="YourProviderName" [providerOptions] type="Provider, ProviderAssembly, Version=, Culture=neutral, PublicKeyToken=" />
27+
<add name="YourProviderName" skipKeepAliveWhenUnused="false" [providerOptions] type="Provider, ProviderAssembly, Version=, Culture=neutral, PublicKeyToken=" />
2828
</providers>
2929
</sessionState>
3030
```
@@ -46,6 +46,7 @@ The specific settings available for the new session state module and providers a
4646

4747
> The mechanics of nuget package upgrade results in removing old elements and re-adding the boiler-plate elements in configuration. To restore In-Memory functionality, set 'RepositoryType' to `InMemory`. To continue using an existing non-memory-optimized table without stored procedures, set 'RespositoryType' to `FrameworkCompat`. The recommendation is to update to the new table schema and use stored procedures with `SqlServer`, but this will ignore existing sessions in previously existing tables.
4848
* Moved to use `Microsoft.Data.SqlClient` instead of old `System.Data.SqlClient`. This allows for more modern features such as Token Authorization.
49+
* Added `skipKeepAliveWhenUnused` to all providers. This setting will skip the call to update expiration time on requests that did not read or write session state. This is setting is used at the module level, and is thus exists on all providers. The default is "false" to maintain compatibility. But certain applications (like MVC) where there can be an abundance of requests processed that never even look at session state could benefit from setting this to "true" to reduce the use of and contention within the session state store. Setting this to "true" does mean that a session needs to be used (not necessarily updated, but at least requested/queried) to stay alive.
4950
* The Sql provider's `UseInMemoryTable` is deprecated. It will continue to be respected in the absence of `RepositoryType`, but is overridden by that setting if given.
5051
* Sql provider `SessionTableName` - A new setting that allows users to target a specific table in their database rather than being forced to use the default table names.
5152
* CosmosDB `collectionId` is now `containerId` in keeping with the updated terminology from the CosmosDB offering. Please use the updated parameter name when configuring your provider. (The old name will continue to work just the same.)

docs/CosmosDBSessionStateProviderAsync.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Then, register your new provider like so:
88
<sessionState cookieless="false" regenerateExpiredSessionId="true" mode="Custom" customProvider="CosmosDBSessionStateProviderAsync">
99
<providers>
1010
<add name="CosmosDBSessionStateProviderAsync" cosmosDBEndPointSettingKey="cosmosDBEndPointSetting" cosmosDBAuthKeySettingKey="cosmosDBAuthKeySetting"
11-
databaseId="[DataBaseId]" collectionId="[CollectionId]" offerThroughput="5000" connectionMode="Direct" requestTimeout="5"
11+
databaseId="[DataBaseId]" collectionId="[CollectionId]" offerThroughput="5000" connectionMode="Direct" requestTimeout="5" skipKeepAliveWhenUnused="false"
1212
maxConnectionLimit="50" maxRetryAttemptsOnThrottledRequests="10" maxRetryWaitTimeInSeconds="10" consistencyLevel="Session" preferredLocations=""
1313
type="Microsoft.AspNet.SessionState.CosmosDBSessionStateProviderAsync, Microsoft.AspNet.SessionState.CosmosDBSessionStateProviderAsync, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
1414
</providers>
@@ -28,12 +28,14 @@ Then, register your new provider like so:
2828

2929
5. *requestTimeout* - The request timeout in seconds when connecting to the Azure DocumentDB database service.
3030

31-
6. *maxConnectionLimit* - maximum number of concurrent connections allowed for the target service endpoint in the Azure DocumentDB database service.
31+
6. *skipKeepAliveWhenUnused* - This setting will skip the call to update expiration time on requests that did not read or write session state. The default is "false" to maintain compatibility with previous behavior. But certain applications (like MVC) where there can be an abundance of requests processed that never even look at session state could benefit from setting this to "true" to reduce the use of and contention within the session state store. Setting this to "true" does mean that a session needs to be used (not necessarily updated, but at least requested/queried) to stay alive.
3232

33-
7. *maxRetryAttemptsOnThrottledRequests* - the maximum number of retries in the case where the request fails because the Azure DocumentDB database service has applied rate limiting on the client.
33+
7. *maxConnectionLimit* - maximum number of concurrent connections allowed for the target service endpoint in the Azure DocumentDB database service.
3434

35-
8. *maxRetryWaitTimeInSeconds* - The maximum retry time in seconds for the Azure DocumentDB database service.
35+
8. *maxRetryAttemptsOnThrottledRequests* - the maximum number of retries in the case where the request fails because the Azure DocumentDB database service has applied rate limiting on the client.
3636

37-
9. *consistencyLevel* - The [Consistency Level](https://learn.microsoft.com/en-us/azure/cosmos-db/consistency-levels) to use with the CosmosClient. Default is the Cosmos SDK default, which is currently 'Session'.
37+
9. *maxRetryWaitTimeInSeconds* - The maximum retry time in seconds for the Azure DocumentDB database service.
3838

39-
10. *preferredLocations* - Sets the preferred locations(regions) for geo-replicated database accounts in the Azure DocumentDB database service. Use ';' to split multiple locations. e.g. "East US;South Central US;North Europe"
39+
10. *consistencyLevel* - The [Consistency Level](https://learn.microsoft.com/en-us/azure/cosmos-db/consistency-levels) to use with the CosmosClient. Default is the Cosmos SDK default, which is currently 'Session'.
40+
41+
11. *preferredLocations* - Sets the preferred locations(regions) for geo-replicated database accounts in the Azure DocumentDB database service. Use ';' to split multiple locations. e.g. "East US;South Central US;North Europe"

docs/SqlSessionStateProviderAsync.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Then, register your new provider like so:
99
<providers>
1010
<add name="SqlSessionStateProviderAsync" connectionStringName="DefaultConnection" SessionTableName="[string]"
1111
RepositoryType="[SqlServer|InMemory|InMemoryDurable|FrameworkCompat]"
12-
MaxRetryNumber="[int]" RetryInterval="[int]"
12+
MaxRetryNumber="[int]" RetryInterval="[int]" skipKeepAliveWhenUnused="false"
1313
type="Microsoft.AspNet.SessionState.SqlSessionStateProviderAsync, Microsoft.AspNet.SessionState.SqlSessionStateProviderAsync, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
1414
</providers>
1515
</sessionState>
@@ -42,4 +42,6 @@ The old in-box SQL provider allowed for applications to choose between three dat
4242

4343
4. *RetryInterval* - The interval between the retry of executing sql query. The default value is 0.001 sec for in-memorytable mode. Otherwise the default value is 1 sec.
4444

45-
5. **[Deprecated]** *UseInMemoryTable* - In the absence of a value for `RepositoryType`, this setting will be used to determine whether to use Sql server 2016 In-Memory OLTP for sessionstate. However, if `RepositoryType` is specified, that setting takes priority. You can find more details about using In-memory table for sessionstate [on this blog](https://blogs.msdn.microsoft.com/sqlcat/2016/10/26/how-bwin-is-using-sql-server-2016-in-memory-oltp-to-achieve-unprecedented-performance-and-scale/).
45+
5. *skipKeepAliveWhenUnused* - This setting will skip the call to update expiration time on requests that did not read or write session state. The default is "false" to maintain compatibility with previous behavior. But certain applications (like MVC) where there can be an abundance of requests processed that never even look at session state could benefit from setting this to "true" to reduce the use of and contention within the session state store. Setting this to "true" does mean that a session needs to be used (not necessarily updated, but at least requested/queried) to stay alive.
46+
47+
6. **[Deprecated]** *UseInMemoryTable* - In the absence of a value for `RepositoryType`, this setting will be used to determine whether to use Sql server 2016 In-Memory OLTP for sessionstate. However, if `RepositoryType` is specified, that setting takes priority. You can find more details about using In-memory table for sessionstate [on this blog](https://blogs.msdn.microsoft.com/sqlcat/2016/10/26/how-bwin-is-using-sql-server-2016-in-memory-oltp-to-achieve-unprecedented-performance-and-scale/).

src/SessionStateModule/Resources/SR.Designer.cs

Lines changed: 11 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/SessionStateModule/Resources/SR.resx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@
120120
<data name="Error_Occured_Reading_Config_Secion" xml:space="preserve">
121121
<value>Error occured when reading config secion '{0}'.</value>
122122
</data>
123+
<data name="Invalid_provider_option" xml:space="preserve">
124+
<value>The value for the '{0}' option on provider name '{1}' is invalid.</value>
125+
</data>
123126
<data name="Invalid_session_custom_provider" xml:space="preserve">
124127
<value>The custom session state store provider name '{0}' is invalid.</value>
125128
</data>
@@ -141,4 +144,4 @@
141144
<data name="Type_doesnt_inherit_from_type" xml:space="preserve">
142145
<value>Type '{0}' does not inherit from '{1}'.</value>
143146
</data>
144-
</root>
147+
</root>

src/SessionStateModule/SessionStateModuleAsync.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ private async Task AcquireStateAsync(HttpApplication app)
406406
_rqId = _idManager.GetSessionID(context);
407407
if (!_rqRequiresState)
408408
{
409-
if (_rqId != null)
409+
if (_rqId != null && !_store.SkipKeepAliveWhenUnused)
410410
{
411411
// Still need to update the sliding timeout to keep session alive.
412412
// There is a plan to skip this for perf reason. But it was postponed to

src/SessionStateModule/SessionStateStoreProviderAsyncBase.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33

44
namespace Microsoft.AspNet.SessionState
55
{
6+
using Microsoft.AspNet.SessionState.Resources;
67
using System;
8+
using System.Collections.Specialized;
9+
using System.Configuration;
710
using System.Configuration.Provider;
811
using System.Threading;
912
using System.Threading.Tasks;
@@ -192,5 +195,24 @@ public abstract Task SetAndReleaseItemExclusiveAsync(
192195
/// <param name="expireCallback"></param>
193196
/// <returns></returns>
194197
public abstract bool SetItemExpireCallback(SessionStateItemExpireCallback expireCallback);
198+
199+
/// <inheritdoc />
200+
public override void Initialize(string name, NameValueCollection config)
201+
{
202+
base.Initialize(name, config);
203+
204+
// This is really a module-level setting, but it can't be specified within the rigid typed xml structure of the session-state module.
205+
// So we have inserted this setting here and it will apply to all providers that this async module can use.
206+
207+
// skipKeepAliveWhenUnused
208+
var skipKA = config["skipKeepAliveWhenUnused"];
209+
if (skipKA != null && !bool.TryParse(skipKA, out _skipKeepAliveWhenUnused))
210+
{
211+
throw new ConfigurationErrorsException(string.Format(SR.Invalid_provider_option, "skipKeepAliveWhenUnused", name));
212+
}
213+
}
214+
215+
private bool _skipKeepAliveWhenUnused = false;
216+
internal bool SkipKeepAliveWhenUnused { get { return _skipKeepAliveWhenUnused; } }
195217
}
196218
}

0 commit comments

Comments
 (0)