/// <summary> /// deletes the session information from the data store where the data store item matches the supplied SessionID value, /// the current application, and the supplied lock identifier. /// </summary> /// <param name="context">The HttpContext instance for the current request</param> /// <param name="sessionId">The session identifier.</param> /// <param name="lockId">The exclusive-lock identifier.</param> /// <param name="item"></param> public override void RemoveItem(HttpContext context, string sessionId, object lockId, SessionStateStoreData item) { try { Logger.Debug("Beginning RemoveItem. SessionId={0}; Application={1}; lockId={2}.", sessionId, ApplicationName, lockId); using (var documentSession = _documentStore.OpenSession()) { //don't tolerate stale data documentSession.Advanced.AllowNonAuthoritativeInformation = false; var sessionStateDocument = documentSession .Load <SessionStateDocument>(SessionStateDocument.GenerateDocumentId(sessionId, ApplicationName)); if (sessionStateDocument != null && sessionStateDocument.LockId == (int)lockId) { documentSession.Delete(sessionStateDocument); documentSession.SaveChanges(); } } Logger.Debug("Completed RemoveItem. SessionId={0}; Application={1}; lockId={2}.", sessionId, ApplicationName, lockId); } catch (Exception ex) { Logger.ErrorException(string.Format("Error during RemoveItem. SessionId={0}; Application={1}; lockId={2}", sessionId, ApplicationName, lockId), ex); throw; } }
/// <summary> /// Adds an uninitialized item to the session data store. /// </summary> /// <param name="context">The HttpContext instance for the current request</param> /// <param name="sessionId">The session identifier.</param> /// <param name="timeout">The expiry timeout in minutes.</param> public override void CreateUninitializedItem(HttpContext context, string sessionId, int timeout) { try { Logger.Debug("Beginning CreateUninitializedItem. SessionId={0}; Application={1}; timeout={1}.", sessionId, ApplicationName, timeout); using (var documentSession = _documentStore.OpenSession()) { var expiry = DateTime.UtcNow.AddMinutes(timeout); var sessionStateDocument = new SessionStateDocument(sessionId, ApplicationName) { Expiry = expiry }; documentSession.Store(sessionStateDocument); documentSession.Advanced.GetMetadataFor(sessionStateDocument)["Raven-Expiration-Date"] = new RavenJValue(expiry); documentSession.SaveChanges(); } Logger.Debug("Completed CreateUninitializedItem. Sessionid={0}; Application={1}; timeout={1}.", sessionId, ApplicationName, timeout); } catch (Exception ex) { Logger.ErrorException("Error during CreateUninitializedItem.", ex); throw; } }
/// <summary> /// Releases the lock on an item in the session data store. /// </summary> /// <param name="context">The HttpContext instance for the current request</param> /// <param name="sessionId">The session identifier.</param> /// <param name="lockId">The lock identifier for the current request.</param> public override void ReleaseItemExclusive(HttpContext context, string sessionId, object lockId) { try { Logger.Debug("Beginning ReleaseItemExclusive. SessionId={0}; Application={1}; LockId={2}.", sessionId, ApplicationName, lockId); using (var documentSession = _documentStore.OpenSession()) { //don't tolerate stale data documentSession.Advanced.AllowNonAuthoritativeInformation = false; var sessionState = documentSession .Load <SessionStateDocument>(SessionStateDocument.GenerateDocumentId(sessionId, ApplicationName)); //if the session-state is not present (it may have expired and been removed) or //the locked id does not match, then we do nothing if (sessionState == null || sessionState.LockId != (int)lockId) { Logger.Debug( "Session state was not present or lock id did not match. Session id: {0}; Application: {1}; Lock id: {2}.", sessionId, ApplicationName, lockId); return; } sessionState.Locked = false; //update the expiry var expiry = DateTime.UtcNow.AddMinutes(SessionStateConfig.Timeout.TotalMinutes); sessionState.Expiry = expiry; documentSession.Advanced.GetMetadataFor(sessionState)["Raven-Expiration-Date"] = new RavenJValue(expiry); documentSession.SaveChanges(); } Logger.Debug("Completed ReleaseItemExclusive. SessionId={0}; Application={1}; LockId={2}.", sessionId, ApplicationName, lockId); } catch (Exception ex) { Logger.ErrorException(string.Format("Error during ReleaseItemExclusive. SessionId={0}; Application={1}; LockId={2}.", sessionId, ApplicationName, lockId), ex); throw; } }
/// <summary> /// Resets the expiry timeout for a session item. /// </summary> /// <param name="context">The HttpContext instance for the current request</param> /// <param name="sessionId">The session identifier.</param> public override void ResetItemTimeout(HttpContext context, string sessionId) { try { Logger.Debug("Beginning ResetItemTimeout. SessionId={0}; Application={1}.", sessionId, ApplicationName); using (var documentSession = _documentStore.OpenSession()) { //we never want to over-write data with this method documentSession.Advanced.UseOptimisticConcurrency = true; var sessionStateDocument = documentSession .Load <SessionStateDocument>(SessionStateDocument.GenerateDocumentId(sessionId, ApplicationName)); if (sessionStateDocument != null) { var expiry = DateTime.UtcNow.AddMinutes(SessionStateConfig.Timeout.TotalMinutes); sessionStateDocument.Expiry = expiry; documentSession.Advanced.GetMetadataFor(sessionStateDocument)["Raven-Expiration-Date"] = new RavenJValue(expiry); documentSession.SaveChanges(); } } Logger.Debug("Completed ResetItemTimeout. SessionId={0}; Application={1}.", sessionId, ApplicationName); } catch (ConcurrencyException ex) { //swallow, we don't care } catch (Exception ex) { Logger.ErrorException("Error during ResetItemTimeout. SessionId=" + sessionId, ex); throw; } }
// // GetSessionStoreItem is called by both the GetItem and // GetItemExclusive methods. GetSessionStoreItem retrieves the // session data from the data source. If the lockRecord parameter // is true (in the case of GetItemExclusive), then GetSessionStoreItem // locks the record and sets a new LockId and LockDate. // private SessionStateStoreData GetSessionStoreItem(bool lockRecord, HttpContext context, string sessionId, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actionFlags) { // Initial values for return value and out parameters. lockAge = TimeSpan.Zero; lockId = null; locked = false; actionFlags = 0; using (var documentSession = _documentStore.OpenSession()) { //don't tolerate stale data documentSession.Advanced.AllowNonAuthoritativeInformation = false; Logger.Debug("Retrieving item from RavenDB. SessionId: {0}; Application: {1}.", sessionId, ApplicationName); var sessionState = documentSession.Load <SessionStateDocument>(SessionStateDocument.GenerateDocumentId(sessionId, ApplicationName)); if (sessionState == null) { Logger.Debug("Item not found in RavenDB with SessionId: {0}; Application: {1}.", sessionId, ApplicationName); return(null); } //if the record is locked, we can't have it. if (sessionState.Locked) { Logger.Debug("Item retrieved is locked. SessionId: {0}; Application: {1}.", sessionId, ApplicationName); locked = true; lockAge = DateTime.UtcNow.Subtract((DateTime)sessionState.LockDate); lockId = sessionState.LockId; return(null); } //generally we shouldn't get expired items, as the expiration bundle should clean them up, //but just in case the bundle isn't installed, or we made the window, we'll delete expired items here. if (DateTime.UtcNow > sessionState.Expiry) { Logger.Debug("Item retrieved has expired. SessionId: {0}; Application: {1}; Expiry (UTC): {2}", sessionId, ApplicationName, sessionState.Expiry); try { documentSession.Delete(sessionState); documentSession.SaveChanges(); } catch (Exception ex) { //we never want this clean-up op to throw Logger.DebugException("Exception thrown while attempting to remove expired item.", ex); } return(null); } if (lockRecord) { sessionState.Locked = true; sessionState.LockId += 1; sessionState.LockDate = DateTime.UtcNow; documentSession.SaveChanges(); } lockId = sessionState.LockId; return (sessionState.Flags == SessionStateActions.InitializeItem ? new SessionStateStoreData(new SessionStateItemCollection(), GetSessionStaticObjects(context), (int)SessionStateConfig.Timeout.TotalMinutes) : Deserialize(context, sessionState.SessionItems, (int)SessionStateConfig.Timeout.TotalMinutes)); } }
/// <summary> /// If the newItem parameter is true, the SetAndReleaseItemExclusive method inserts a new item into the data store with the supplied values. /// Otherwise, the existing item in the data store is updated with the supplied values, and any lock on the data is released. /// </summary> /// <param name="context">The HttpContext instance for the current request</param> /// <param name="sessionId">The session identifier.</param> /// <param name="item">The current session values to be stored</param> /// <param name="lockId">The lock identifier for the current request.</param> /// <param name="newItem">If true, a new item is inserted into the store. Otherwise, the existing item in /// the data store is updated with the supplied values, and any lock on the data is released. </param> public override void SetAndReleaseItemExclusive(HttpContext context, string sessionId, SessionStateStoreData item, object lockId, bool newItem) { try { Logger.Debug( " Beginning SetAndReleaseItemExclusive. SessionId={0}, Application: {1}, LockId={2}, newItem={3}.", sessionId, ApplicationName, lockId, newItem); if (item == null) { throw new ArgumentNullException("item"); } var serializedItems = Serialize((SessionStateItemCollection)item.Items); using (var documentSession = _documentStore.OpenSession()) { //don't tolerate stale data documentSession.Advanced.AllowNonAuthoritativeInformation = false; SessionStateDocument sessionStateDocument; if (newItem) //if we are creating a new document { sessionStateDocument = new SessionStateDocument(sessionId, ApplicationName); documentSession.Store(sessionStateDocument); } else //we are not creating a new document, so load it { sessionStateDocument = documentSession.Load <SessionStateDocument>(SessionStateDocument.GenerateDocumentId(sessionId, ApplicationName)); //if the lock identifier does not match, then we don't modifiy the data if (sessionStateDocument.LockId != (int)lockId) { Logger.Debug( "Lock Id does not match, so data will not be modified. Session Id: {0}; Application: {1}; Lock Id {2}.", sessionId, ApplicationName, lockId); return; } } sessionStateDocument.SessionItems = serializedItems; sessionStateDocument.Locked = false; //set the expiry var expiry = DateTime.UtcNow.AddMinutes(SessionStateConfig.Timeout.TotalMinutes); sessionStateDocument.Expiry = expiry; documentSession.Advanced.GetMetadataFor(sessionStateDocument)["Raven-Expiration-Date"] = new RavenJValue(expiry); documentSession.SaveChanges(); } Logger.Debug("Completed SetAndReleaseItemExclusive. SessionId={0}; Application:{1}; LockId={2}; newItem={3}.", sessionId, ApplicationName, lockId, newItem); } catch (Exception ex) { Logger.ErrorException(string.Format("Error during SetAndReleaseItemExclusive. SessionId={0}; Application={1}; LockId={2}, newItem={3}.", sessionId, ApplicationName, lockId, newItem), ex); throw; } }
/// <summary> /// Adds an uninitialized item to the session data store. /// </summary> /// <param name="context">The HttpContext instance for the current request</param> /// <param name="sessionId">The session identifier.</param> /// <param name="timeout">The expiry timeout in minutes.</param> public override void CreateUninitializedItem(HttpContext context, string sessionId, int timeout) { try { Logger.Debug("Beginning CreateUninitializedItem. SessionId={0}; Application={1}; timeout={1}.", sessionId, ApplicationName, timeout); using (var documentSession = _documentStore.OpenSession()) { var expiry = DateTime.UtcNow.AddMinutes(timeout); var sessionStateDocument = new SessionStateDocument(sessionId, ApplicationName) { Expiry = expiry }; documentSession.Store(sessionStateDocument); documentSession.Advanced.GetMetadataFor(sessionStateDocument)["Raven-Expiration-Date"] = new RavenJValue(expiry); documentSession.SaveChanges(); } Logger.Debug("Completed CreateUninitializedItem. Sessionid={0}; Application={1}; timeout={1}.", sessionId, ApplicationName, timeout); } catch (Exception ex) { Logger.ErrorException("Error during CreateUninitializedItem.", ex); throw; } }
/// <summary> /// If the newItem parameter is true, the SetAndReleaseItemExclusive method inserts a new item into the data store with the supplied values. /// Otherwise, the existing item in the data store is updated with the supplied values, and any lock on the data is released. /// </summary> /// <param name="context">The HttpContext instance for the current request</param> /// <param name="sessionId">The session identifier.</param> /// <param name="item">The current session values to be stored</param> /// <param name="lockId">The lock identifier for the current request.</param> /// <param name="newItem">If true, a new item is inserted into the store. Otherwise, the existing item in /// the data store is updated with the supplied values, and any lock on the data is released. </param> public override void SetAndReleaseItemExclusive(HttpContext context, string sessionId, SessionStateStoreData item, object lockId, bool newItem) { try { Logger.Debug( " Beginning SetAndReleaseItemExclusive. SessionId={0}, Application: {1}, LockId={2}, newItem={3}.", sessionId, ApplicationName, lockId, newItem); if ( item == null) throw new ArgumentNullException("item"); var serializedItems = Serialize((SessionStateItemCollection) item.Items); using (var documentSession = _documentStore.OpenSession()) { //don't tolerate stale data documentSession.Advanced.AllowNonAuthoritativeInformation = false; SessionStateDocument sessionStateDocument; if (newItem) //if we are creating a new document { sessionStateDocument = new SessionStateDocument(sessionId, ApplicationName); documentSession.Store(sessionStateDocument); } else //we are not creating a new document, so load it { sessionStateDocument = documentSession .Load<SessionStateDocument>(SessionStateDocument.GenerateDocumentId( sessionId, ApplicationName)); //if the lock identifier does not match, then we don't modifiy the data if (sessionStateDocument.LockId != (int) lockId) { Logger.Debug( "Lock Id does not match, so data will not be modified. Session Id: {0}; Application: {1}; Lock Id {2}.", sessionId, ApplicationName, lockId); return; } } sessionStateDocument.SessionItems = serializedItems; sessionStateDocument.Locked = false; //set the expiry var expiry = DateTime.UtcNow.AddMinutes(SessionStateConfig.Timeout.TotalMinutes); sessionStateDocument.Expiry = expiry; documentSession.Advanced.GetMetadataFor(sessionStateDocument)["Raven-Expiration-Date"] = new RavenJValue(expiry); documentSession.SaveChanges(); } Logger.Debug("Completed SetAndReleaseItemExclusive. SessionId={0}; Application:{1}; LockId={2}; newItem={3}.", sessionId, ApplicationName, lockId, newItem); } catch(Exception ex) { Logger.ErrorException(string.Format("Error during SetAndReleaseItemExclusive. SessionId={0}; Application={1}; LockId={2}, newItem={3}.", sessionId, ApplicationName, lockId, newItem), ex); throw; } }