public override void SetAndReleaseItemExclusive(HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem) { try { if (LastException == null) { GetAccessToStore(id); // If it is new record if (newItem) { ISessionStateItemCollection sessionItems = null; if (item != null && item.Items != null) { sessionItems = item.Items; } else { sessionItems = new ChangeTrackingSessionStateItemCollection(); } if (sessionItems["SessionStateActions"] != null) { sessionItems.Remove("SessionStateActions"); } // Converting timout from min to sec cache.Set(sessionItems, (item.Timeout * FROM_MIN_TO_SEC)); LogUtility.LogInfo("SetAndReleaseItemExclusive => Session Id: {0}, Session provider object: {1} => created new item in session.", id, this.GetHashCode()); } // If update if lock matches else { if (item != null && item.Items != null) { if (item.Items["SessionStateActions"] != null) { item.Items.Remove("SessionStateActions"); } // Converting timout from min to sec cache.TryUpdateAndReleaseLockIfLockIdMatch(lockId, item.Items, (item.Timeout * FROM_MIN_TO_SEC)); LogUtility.LogInfo("SetAndReleaseItemExclusive => Session Id: {0}, Session provider object: {1} => updated item in session.", id, this.GetHashCode()); } } } } catch (Exception e) { LogUtility.LogError("SetAndReleaseItemExclusive => {0}", e.ToString()); LastException = e; if (configuration.ThrowOnError) { throw; } } }
internal static ProviderConfiguration ProviderConfigurationForOutputCache(NameValueCollection config) { ProviderConfiguration configuration = new ProviderConfiguration(config); // No retry login for output cache provider configuration.RetryTimeout = TimeSpan.Zero; // Session state specific attribute which are not applicable to output cache configuration.ThrowOnError = true; configuration.RequestTimeout = TimeSpan.Zero; configuration.SessionTimeout = TimeSpan.Zero; LogUtility.LogInfo("Host: {0}, Port: {1}, UseSsl: {2}, DatabaseId: {3}, ApplicationName: {4}", configuration.Host, configuration.Port, configuration.UseSsl, configuration.DatabaseId, configuration.ApplicationName); return(configuration); }
public void ForceReconnect() { var previousReconnect = lastReconnectTime; var elapsedSinceLastReconnect = DateTimeOffset.UtcNow - previousReconnect; // If mulitple threads call ForceReconnect at the same time, we only want to honor one of them. if (elapsedSinceLastReconnect > ReconnectFrequency) { lock (reconnectLock) { var utcNow = DateTimeOffset.UtcNow; elapsedSinceLastReconnect = utcNow - lastReconnectTime; if (elapsedSinceLastReconnect < ReconnectFrequency) { return; // Some other thread made it through the check and the lock, so nothing to do. } if (firstErrorTime == DateTimeOffset.MinValue) { // We got error first time after last reconnect firstErrorTime = utcNow; previousErrorTime = utcNow; return; } var elapsedSinceFirstError = utcNow - firstErrorTime; var elapsedSinceMostRecentError = utcNow - previousErrorTime; previousErrorTime = utcNow; if ((elapsedSinceFirstError >= ReconnectErrorThreshold) && (elapsedSinceMostRecentError <= ReconnectErrorThreshold)) { LogUtility.LogInfo($"ForceReconnect: now: {utcNow.ToString()}"); LogUtility.LogInfo($"ForceReconnect: elapsedSinceLastReconnect: {elapsedSinceLastReconnect.ToString()}, ReconnectFrequency: {ReconnectFrequency.ToString()}"); LogUtility.LogInfo($"ForceReconnect: elapsedSinceFirstError: {elapsedSinceFirstError.ToString()}, elapsedSinceMostRecentError: {elapsedSinceMostRecentError.ToString()}, ReconnectErrorThreshold: {ReconnectErrorThreshold.ToString()}"); firstErrorTime = DateTimeOffset.MinValue; previousErrorTime = DateTimeOffset.MinValue; var oldMultiplexer = _redisMultiplexer; CloseMultiplexer(oldMultiplexer); CreateMultiplexer(); } } } }
internal static ProviderConfiguration ProviderConfigurationForObjectCache(NameValueCollection config, string cacheName) { ProviderConfiguration configuration = new ProviderConfiguration(config); configuration.RetryTimeout = TimeSpan.Zero; configuration.ThrowOnError = GetBoolSettings(config, "throwOnError", false); // Session state specific attribute which are not applicable to output cache configuration.RequestTimeout = TimeSpan.Zero; configuration.SessionTimeout = TimeSpan.Zero; configuration.ApplicationName += "_ObjectCache_" + cacheName; LogUtility.LogInfo("Host: {0}, Port: {1}, UseSsl: {2}, DatabaseId: {3}, ApplicationName: {4}, ThrowOnError: {5}", configuration.Host, configuration.Port, configuration.UseSsl, configuration.DatabaseId, configuration.ApplicationName, configuration.ThrowOnError); return(configuration); }
private ProviderConfiguration(NameValueCollection config) { EnableLoggingIfParametersAvailable(config); // Get connection host, port and password. // host, port, accessKey and ssl are firest fetched from appSettings if not found there than taken from web.config ConnectionString = GetConnectionString(config); Host = GetStringSettings(config, "host", "127.0.0.1"); Port = GetIntSettings(config, "port", 0); AccessKey = GetStringSettings(config, "accessKey", null); UseSsl = GetBoolSettings(config, "ssl", true); RedisSerializerType = GetStringSettings(config, "redisSerializerType", null); ConnectionMultiplexerFactoryType = GetStringSettings(config, "connectionMultiplexerFactoryType", null); // All below parameters are only fetched from web.config DatabaseId = GetIntSettings(config, "databaseId", 0); ApplicationName = GetStringSettings(config, "applicationName", null); if (ApplicationName == null) { try { ApplicationName = HostingEnvironment.ApplicationVirtualPath; if (String.IsNullOrEmpty(ApplicationName)) { ApplicationName = System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName; int indexOfDot = ApplicationName.IndexOf('.'); if (indexOfDot != -1) { ApplicationName = ApplicationName.Remove(indexOfDot); } } if (String.IsNullOrEmpty(ApplicationName)) { ApplicationName = "/"; } } catch (Exception e) { ApplicationName = "/"; LogUtility.LogInfo(e.Message); } } ConnectionTimeoutInMilliSec = GetIntSettings(config, "connectionTimeoutInMilliseconds", 0); OperationTimeoutInMilliSec = GetIntSettings(config, "operationTimeoutInMilliseconds", 0); }
public override void RemoveItem(HttpContext context, string id, object lockId, SessionStateStoreData item) { try { if (LastException == null && lockId != null) { LogUtility.LogInfo("RemoveItem => Session Id: {0}, Session provider object: {1}.", id, this.GetHashCode()); GetAccessToStore(id); cache.TryRemoveAndReleaseLockIfLockIdMatch(lockId); } } catch (Exception e) { LogUtility.LogError("RemoveItem => {0}", e.ToString()); LastException = e; if (configuration.ThrowOnError) { throw; } } }
public override void ResetItemTimeout(HttpContext context, string id) { try { if (LastException == null) { LogUtility.LogInfo("ResetItemTimeout => Session Id: {0}, Session provider object: {1}.", id, this.GetHashCode()); GetAccessToStore(id); cache.UpdateExpiryTime((int)configuration.SessionTimeout.TotalSeconds); cache = null; } } catch (Exception e) { LogUtility.LogError("ResetItemTimeout => {0}", e.ToString()); LastException = e; if (configuration.ThrowOnError) { throw; } } }
public override async Task RemoveItemAsync(HttpContextBase context, string id, object lockId, SessionStateStoreData item, CancellationToken cancellationToken) { try { if (LastException == null) { LogUtility.LogInfo("RemoveItem => Session Id: {0}, Session provider object: {1}, Lock ID: {2}.", id, this.GetHashCode(), lockId); GetAccessToStore(id); cache.TryRemoveAndReleaseLock(lockId); } } catch (Exception e) { LogUtility.LogError("RemoveItem => {0}", e.ToString()); LastException = e; if (configuration.ThrowOnError) { throw; } } await Task.FromResult(0); }
public override async Task ReleaseItemExclusiveAsync(HttpContextBase context, string id, object lockId, CancellationToken cancellationToken) { try { // This check is required for unit tests to work int sessionTimeoutInSeconds; if (context != null && context.Session != null) { sessionTimeoutInSeconds = context.Session.Timeout * FROM_MIN_TO_SEC; } else { sessionTimeoutInSeconds = (int)configuration.SessionTimeout.TotalSeconds; } if (LastException == null && lockId != null) { LogUtility.LogInfo("ReleaseItemExclusive => Session Id: {0}, Session provider object: {1} => For lockId: {2}.", id, this.GetHashCode(), lockId); GetAccessToStore(id); cache.TryReleaseLockIfLockIdMatch(lockId, sessionTimeoutInSeconds); // Either already released lock successfully inside above if block // Or we do not hold lock so we should not release it. sessionId = null; sessionLockId = null; } } catch (Exception e) { LogUtility.LogError("ReleaseItemExclusive => {0}", e.ToString()); LastException = e; if (configuration.ThrowOnError) { throw; } } await Task.FromResult(0); }
internal static ProviderConfiguration ProviderConfigurationForSessionState(NameValueCollection config) { ProviderConfiguration configuration = new ProviderConfiguration(config); configuration.ThrowOnError = GetBoolSettings(config, "throwOnError", true); int retryTimeoutInMilliSec = GetIntSettings(config, "retryTimeoutInMilliseconds", 5000); configuration.RetryTimeout = new TimeSpan(0, 0, 0, 0, retryTimeoutInMilliSec); // Get request timeout from config HttpRuntimeSection httpRuntimeSection = ConfigurationManager.GetSection("system.web/httpRuntime") as HttpRuntimeSection; configuration.RequestTimeout = httpRuntimeSection.ExecutionTimeout; // Get session timeout from config SessionStateSection sessionStateSection = (SessionStateSection)WebConfigurationManager.GetSection("system.web/sessionState"); configuration.SessionTimeout = sessionStateSection.Timeout; LogUtility.LogInfo("Host: {0}, Port: {1}, ThrowOnError: {2}, UseSsl: {3}, RetryTimeout: {4}, DatabaseId: {5}, ApplicationName: {6}, RequestTimeout: {7}, SessionTimeout: {8}", configuration.Host, configuration.Port, configuration.ThrowOnError, configuration.UseSsl, configuration.RetryTimeout, configuration.DatabaseId, configuration.ApplicationName, configuration.RequestTimeout, configuration.SessionTimeout); return(configuration); }
public override async Task ResetItemTimeoutAsync(HttpContextBase context, string id, CancellationToken cancellationToken) { try { if (LastException == null) { LogUtility.LogInfo("ResetItemTimeout => Session Id: {0}, Session provider object: {1}.", id, this.GetHashCode()); GetAccessToStore(id); cache.UpdateExpiryTime((int)configuration.SessionTimeout.TotalSeconds); cache = null; } } catch (Exception e) { LogUtility.LogError("ResetItemTimeout => {0}", e.ToString()); LastException = e; if (configuration.ThrowOnError) { throw; } } await Task.FromResult(0); }
public override void CreateUninitializedItem(HttpContext context, string id, int timeout) { try { if (LastException == null) { LogUtility.LogInfo("CreateUninitializedItem => Session Id: {0}, Session provider object: {1}.", id, this.GetHashCode()); ISessionStateItemCollection sessionData = new ChangeTrackingSessionStateItemCollection(); sessionData["SessionStateActions"] = SessionStateActions.InitializeItem; GetAccessToStore(id); // Converting timout from min to sec cache.Set(sessionData, (timeout * FROM_MIN_TO_SEC)); } } catch (Exception e) { LogUtility.LogError("CreateUninitializedItem => {0}", e.ToString()); LastException = e; if (configuration.ThrowOnError) { throw; } } }
public override void EndRequest(HttpContext context) { try { if (sessionId != null && sessionLockId != null) { GetAccessToStore(sessionId); cache.TryReleaseLockIfLockIdMatch(sessionLockId); LogUtility.LogInfo("EndRequest => Session Id: {0}, Session provider object: {1} => Lock Released with lockId {2}.", sessionId, this.GetHashCode(), sessionLockId); sessionId = null; sessionLockId = null; } cache = null; } catch (Exception e) { LogUtility.LogError("EndRequest => {0}", e.ToString()); LastException = e; if (configuration.ThrowOnError) { throw; } } }
public override async Task EndRequestAsync(HttpContextBase context) { try { // This check is required for unit tests to work int sessionTimeoutInSeconds; if (context != null && context.Session != null) { sessionTimeoutInSeconds = context.Session.Timeout * FROM_MIN_TO_SEC; } else { sessionTimeoutInSeconds = (int)configuration.SessionTimeout.TotalSeconds; } if (sessionId != null && sessionLockId != null) { GetAccessToStore(sessionId); cache.TryReleaseLockIfLockIdMatch(sessionLockId, sessionTimeoutInSeconds); LogUtility.LogInfo("EndRequest => Session Id: {0}, Session provider object: {1} => Lock Released with lockId {2}.", sessionId, this.GetHashCode(), sessionLockId); sessionId = null; sessionLockId = null; } cache = null; } catch (Exception e) { LogUtility.LogError("EndRequest => {0}", e.ToString()); LastException = e; if (configuration.ThrowOnError) { throw; } } await Task.FromResult(0); }
private SessionStateStoreData GetItemFromSessionStore(bool isWriteLockRequired, HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { try { SessionStateStoreData sessionStateStoreData = null; locked = false; lockAge = TimeSpan.Zero; lockId = 0; actions = SessionStateActions.None; GetAccessToStore(id); ISessionStateItemCollection sessionData = null; int sessionTimeout; bool isLockTaken = false; //Take read or write lock and if locking successful than get data in sessionData and also update session timeout if (isWriteLockRequired) { isLockTaken = cache.TryTakeWriteLockAndGetData(DateTime.Now, (int)configuration.RequestTimeout.TotalSeconds, out lockId, out sessionData, out sessionTimeout); sessionId = id; // signal that we have to remove lock in EndRequest sessionLockId = lockId; // save lockId for EndRequest } else { isLockTaken = cache.TryCheckWriteLockAndGetData(out lockId, out sessionData, out sessionTimeout); } if (isLockTaken) { locked = false; LogUtility.LogInfo("GetItemFromSessionStore => Session Id: {0}, Session provider object: {1} => Lock taken with lockId: {2}", id, this.GetHashCode(), lockId); } else { sessionId = null; sessionLockId = null; locked = true; LogUtility.LogInfo("GetItemFromSessionStore => Session Id: {0}, Session provider object: {1} => Can not lock, Someone else has lock and lockId is {2}", id, this.GetHashCode(), lockId); } // If locking is not successful then do not return any result just return lockAge, locked=true and lockId. // ASP.NET tries to acquire lock again in 0.5 sec by calling this method again. Using lockAge it finds if // lock has been taken more than http request timeout than ASP.NET calls ReleaseItemExclusive and calls this method again to get lock. if (locked) { lockAge = cache.GetLockAge(lockId); return(null); } if (sessionData == null) { // If session data do not exists means it might be exipred and removed. So return null so that asp.net can call CreateUninitializedItem and start again. // But we just locked the record so first release it ReleaseItemExclusive(context, id, lockId); return(null); } // Restore action flag from session data if (sessionData["SessionStateActions"] != null) { actions = (SessionStateActions)sessionData["SessionStateActions"]; } //Get data related to this session from sessionDataDictionary and populate session items sessionData.Dirty = false; sessionStateStoreData = new SessionStateStoreData(sessionData, new HttpStaticObjectsCollection(), sessionTimeout); return(sessionStateStoreData); } catch (Exception e) { LogUtility.LogError("GetItemFromSessionStore => {0}", e.ToString()); locked = false; lockId = null; lockAge = TimeSpan.Zero; actions = 0; LastException = e; if (configuration.ThrowOnError) { throw; } return(null); } }
public override SessionStateStoreData GetItemExclusive(HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { LogUtility.LogInfo("GetItemExclusive => Session Id: {0}, Session provider object: {1}.", id, this.GetHashCode()); return(GetItemFromSessionStore(true, context, id, out locked, out lockAge, out lockId, out actions)); }
public override SessionStateStoreData CreateNewStoreData(HttpContext context, int timeout) { //Creating empty session store data and return it. LogUtility.LogInfo("CreateNewStoreData => Session provider object: {0}.", this.GetHashCode()); return(new SessionStateStoreData(new ChangeTrackingSessionStateItemCollection(), new HttpStaticObjectsCollection(), timeout)); }