public override void SetAndReleaseItemExclusive(HttpContext context, string id, SessionStateStoreData item, object lockIdObject, bool newItem) { _log.DebugFormat("SetAndReleaseItemExclusive({0})", id); LogExceptions("SetAndReleaseItemExclusive()", () => { #if DEBUG // To test the exception handling code. if (null != item.Items["throwthrowthrow"]) { throw new Exception("throwthrowthrow"); } #endif SessionLockEntity lockId = (SessionLockEntity)lockIdObject; SessionEntity sessionItems = new SessionEntity(); sessionItems.Id = id; if (newItem) { // Insert new SessionLock and SessionItems. sessionItems.Items = Serialize((SessionStateItemCollection)item.Items); sessionItems.ReleaseCount = 0; SessionLockEntity sessionLock = new SessionLockEntity { Id = id, TimeOutInMinutes = item.Timeout, ExpirationDate = DateTime.UtcNow.AddMinutes(item.Timeout), DateLocked = DateTime.UtcNow, LockCount = 0 }; using (new LifetimeTimer(_log, "SetAndReleaseItemExclusive(new)", 25)) using (var transaction = _datastore.BeginTransaction(_callSettings)) { transaction.Upsert(ToEntity(sessionItems), ToEntity(sessionLock)); transaction.Commit(_callSettings); } return; } using (new LifetimeTimer(_log, "SetAndReleaseItemExclusive", 25)) using (var transaction = _datastore.BeginTransaction(_callSettings)) { // Update existing session items. sessionItems.Items = item.Items.Dirty ? Serialize((SessionStateItemCollection)item.Items) : lockId.Items; // Unlock the session. sessionItems.ReleaseCount = lockId.LockCount; SessionLockEntity sessionLock = SessionLockFromEntity( transaction.Lookup(_lockKeyFactory.CreateKey(id), _callSettings)); if (sessionLock == null || sessionLock.LockCount != lockId.LockCount) { return; // Something else locked it in the meantime. } transaction.Upsert(ToEntity(sessionItems)); transaction.Commit(_callSettings); } }); }
/// <summary> /// Pack a SessionLock into a Datastore entity. /// </summary> private Entity ToEntity(SessionLockEntity sessionLock) { var entity = new Entity(); entity.Key = _lockKeyFactory.CreateKey(sessionLock.Id); entity[LOCK_COUNT] = sessionLock.LockCount; entity[LOCK_DATE] = sessionLock.DateLocked; entity[TIMEOUT] = sessionLock.TimeOutInMinutes; entity[EXPIRES] = sessionLock.ExpirationDate; ExcludeFromIndexes(entity, LOCK_COUNT, LOCK_DATE, TIMEOUT); return(entity); }
/// <summary> /// Unpack a SessionLockEntity from a Datastore entity. /// </summary> /// <param name="entity">The datastore entity.</param> /// <returns>A SessionLock instance. Returns null if entity is null.</returns> private SessionLockEntity SessionLockFromEntity(Entity entity) { if (null == entity) { return(null); } SessionLockEntity sessionLock = new SessionLockEntity(); sessionLock.Id = entity.Key.Path.First().Name; sessionLock.LockCount = (int)entity[LOCK_COUNT]; sessionLock.DateLocked = (DateTime)entity[LOCK_DATE]; sessionLock.ExpirationDate = (DateTime)entity[EXPIRES]; sessionLock.TimeOutInMinutes = (int)entity[TIMEOUT]; return(sessionLock); }
public override void CreateUninitializedItem(HttpContext context, string id, int timeout) { _log.DebugFormat("CreateUninitializedItem({0})", id); LogExceptions("CreateUninitializedItem()", () => { var sessionLock = new SessionLockEntity(); sessionLock.Id = id; sessionLock.ExpirationDate = DateTime.UtcNow.AddMinutes(timeout); sessionLock.TimeOutInMinutes = timeout; sessionLock.DateLocked = DateTime.UtcNow; sessionLock.LockCount = 0; using (new LifetimeTimer(_log, "CreateUninitializedItem", 25)) using (var transaction = _datastore.BeginTransaction(_callSettings)) { transaction.Upsert(ToEntity(sessionLock)); transaction.Delete(_sessionKeyFactory.CreateKey(id)); transaction.Commit(_callSettings); } }); }
public override void RemoveItem(HttpContext context, string id, object lockIdObject, SessionStateStoreData item) { _log.DebugFormat("RemoveItem({0})", id); LogExceptions("RemoveItem()", () => { SessionLockEntity lockId = (SessionLockEntity)lockIdObject; using (new LifetimeTimer(_log, "RemoveItem", 25)) using (var transaction = _datastore.BeginTransaction(_callSettings)) { SessionLockEntity sessionLock = SessionLockFromEntity( transaction.Lookup(_lockKeyFactory.CreateKey(id), _callSettings)); if (sessionLock == null || sessionLock.LockCount != lockId.LockCount) { return; // Something else locked it in the meantime. } transaction.Delete(_sessionKeyFactory.CreateKey(id), _lockKeyFactory.CreateKey(id)); transaction.Commit(_callSettings); } }); }
public override void ReleaseItemExclusive(HttpContext context, string id, object lockIdObject) { _log.DebugFormat("ReleaseItemExclusive({0})", id); LogExceptions("ReleaseItemExclusive()", () => { SessionLockEntity lockId = (SessionLockEntity)lockIdObject; SessionEntity sessionItems = new SessionEntity(); sessionItems.Id = id; sessionItems.ReleaseCount = lockId.LockCount; sessionItems.Items = lockId.Items; using (new LifetimeTimer(_log, "ReleaseItemExclusive", 25)) using (var transaction = _datastore.BeginTransaction(_callSettings)) { SessionLockEntity sessionLock = SessionLockFromEntity( transaction.Lookup(_lockKeyFactory.CreateKey(id), _callSettings)); if (sessionLock == null || sessionLock.LockCount != lockId.LockCount) { return; // Something else locked it in the meantime. } transaction.Upsert(ToEntity(sessionItems)); transaction.Commit(_callSettings); } }); }
public SessionStateStoreData GetItemImpl(bool exclusive, HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { try { using (new LifetimeTimer(_log, "GetItemImpl", 25)) using (var transaction = _datastore.BeginTransaction(_callSettings)) { // Look up both entities in datastore. var entities = transaction.Lookup(new Key[] { _sessionKeyFactory.CreateKey(id), _lockKeyFactory.CreateKey(id) }, _callSettings); SessionLockEntity sessionLock = SessionLockFromEntity(entities[1]); if (sessionLock == null || sessionLock.ExpirationDate < DateTime.UtcNow) { // No such session. lockAge = TimeSpan.Zero; locked = false; lockId = null; actions = SessionStateActions.None; return(null); } SessionEntity sessionItems = SessionFromEntity(id, entities[0]); sessionLock.Items = sessionItems.Items; locked = sessionLock.LockCount > sessionItems.ReleaseCount; lockAge = locked ? DateTime.UtcNow - sessionLock.DateLocked : TimeSpan.Zero; lockId = sessionLock; actions = SessionStateActions.None; if (locked) { return(null); } if (exclusive) { // Lock the session. sessionLock.LockCount = sessionItems.ReleaseCount + 1; sessionLock.DateLocked = DateTime.UtcNow; sessionLock.ExpirationDate = DateTime.UtcNow.AddMinutes(sessionLock.TimeOutInMinutes); transaction.Upsert(ToEntity(sessionLock)); transaction.Commit(_callSettings); locked = true; } return(Deserialize(context, sessionItems.Items, sessionLock.TimeOutInMinutes)); } } catch (Exception e) { _log.Error("GetItemImpl()", e); locked = true; lockAge = TimeSpan.Zero; lockId = 0; actions = SessionStateActions.None; return(null); } }