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);
        }
Beispiel #3
0
        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();
                    }
                }
            }
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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);
        }
Beispiel #6
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;
         }
     }
 }
Beispiel #7
0
 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;
         }
     }
 }
Beispiel #8
0
 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);
 }
Beispiel #9
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);
        }
Beispiel #11
0
 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);
 }
Beispiel #12
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;
         }
     }
 }
Beispiel #13
0
 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;
         }
     }
 }
Beispiel #14
0
        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);
        }
Beispiel #15
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);
            }
        }
Beispiel #16
0
 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));
 }
Beispiel #17
0
 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));
 }