/// <summary> /// /// </summary> /// <param name="context"></param> /// <param name="id"></param> /// <param name="item"></param> /// <param name="lockId"></param> /// <param name="newItem"></param> public override void SetAndReleaseItemExclusive(HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem) { using (var client = GetClient()) { if (newItem) { var state = new RedisSessionState() { Items = (SessionStateItemCollection)item.Items, Timeout = item.Timeout, }; var key = GetSessionIdKey(id); UpdateSessionState(client, key, state); } else { UpdateSessionStateIfLocked(client, id, (int)lockId, state => { state.Items = (SessionStateItemCollection)item.Items; state.Locked = false; state.Timeout = item.Timeout; }); } } }
private SessionStateStoreData GetItem(bool isExclusive, HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { locked = false; lockAge = TimeSpan.Zero; lockId = null; actions = SessionStateActions.None; SessionStateStoreData result = null; var key = GetSessionIdKey(id); using (var client = GetClient()) using (var distributedLock = GetDistributedLock(client, key)) { if (distributedLock.LockState == DistributedLock.LOCK_NOT_ACQUIRED) { options.OnDistributedLockNotAcquired(id); return(null); } var stateRaw = client.GetAllEntriesFromHashRaw(key); RedisSessionState state; if (!RedisSessionState.TryParse(stateRaw, out state)) { return(null); } actions = state.Flags; if (state.Locked) { locked = true; lockId = state.LockId; lockAge = DateTime.UtcNow - state.LockDate; return(null); } if (isExclusive) { locked = state.Locked = true; state.LockDate = DateTime.UtcNow; lockAge = TimeSpan.Zero; lockId = ++state.LockId; } state.Flags = SessionStateActions.None; UseTransaction(client, transaction => { transaction.QueueCommand(c => c.SetRangeInHashRaw(key, state.ToMap())); transaction.QueueCommand(c => c.ExpireEntryIn(key, TimeSpan.FromMinutes(state.Timeout))); }); var items = actions == SessionStateActions.InitializeItem ? new SessionStateItemCollection() : state.Items; result = new SessionStateStoreData(items, staticObjectsGetter(context), state.Timeout); } return(result); }
/// <summary> /// /// </summary> /// <param name="context"></param> /// <param name="id"></param> /// <param name="lockId"></param> /// <param name="item"></param> public override void RemoveItem(HttpContext context, string id, object lockId, SessionStateStoreData item) { var key = GetSessionIdKey(id); using (var client = GetClient()) using (var distributedLock = GetDistributedLock(client, key)) { if (distributedLock.LockState == DistributedLock.LOCK_NOT_ACQUIRED) { options.OnDistributedLockNotAcquired(id); return; } var stateRaw = client.GetAllEntriesFromHashRaw(key); UseTransaction(client, transaction => { RedisSessionState state; if (RedisSessionState.TryParse(stateRaw, out state) && state.Locked && state.LockId == (int)lockId) { transaction.QueueCommand(c => c.Remove(key)); } }); } }
private void UpdateSessionState(IRedisClient client, string key, RedisSessionState state) { UseTransaction(client, transaction => { transaction.QueueCommand(c => c.SetRangeInHashRaw(key, state.ToMap())); transaction.QueueCommand(c => c.ExpireEntryIn(key, TimeSpan.FromMinutes(state.Timeout))); }); }
/// <summary> /// /// </summary> /// <param name="context"></param> /// <param name="id"></param> /// <param name="timeout"></param> public override void CreateUninitializedItem(HttpContext context, string id, int timeout) { var key = GetSessionIdKey(id); using (var client = GetClient()) { var state = new RedisSessionState() { Timeout = timeout, Flags = SessionStateActions.InitializeItem }; UpdateSessionState(client, key, state); } }
private void UpdateSessionStateIfLocked(IRedisClient client, string id, int lockId, Action <RedisSessionState> stateAction) { var key = GetSessionIdKey(id); using (var distributedLock = GetDistributedLock(client, key)) { if (distributedLock.LockState == DistributedLock.LOCK_NOT_ACQUIRED) { options.OnDistributedLockNotAcquired(id); return; } var stateRaw = client.GetAllEntriesFromHashRaw(key); RedisSessionState state; if (RedisSessionState.TryParse(stateRaw, out state) && state.Locked && state.LockId == lockId) { stateAction(state); UpdateSessionState(client, key, state); } } }
public static bool TryParse(IDictionary <string, byte[]> raw, out RedisSessionState data) { if (raw == null || raw.Count != 7) { data = null; return(false); } SessionStateItemCollection sessionItems; using (var ms = new MemoryStream(raw["items"])) { if (ms.Length > 0) { using (var reader = new BinaryReader(ms)) { sessionItems = SessionStateItemCollection.Deserialize(reader); } } else { sessionItems = new SessionStateItemCollection(); } } data = new RedisSessionState() { Created = new DateTime(BitConverter.ToInt64(raw["created"], 0)), Locked = BitConverter.ToBoolean(raw["locked"], 0), LockId = raw["lockId"].Length == 0 ? 0 : BitConverter.ToInt32(raw["lockId"], 0), LockDate = raw["lockDate"].Length == 0 ? DateTime.MinValue : new DateTime(BitConverter.ToInt64(raw["lockDate"], 0)), Timeout = BitConverter.ToInt32(raw["timeout"], 0), Flags = (SessionStateActions)BitConverter.ToInt32(raw["flags"], 0), Items = sessionItems }; return(true); }