public override void SetAndReleaseItemExclusive(HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem) { // 1 remote call #region Access Log #if TRACE { Handler.LogHandler.Tracking("Access Method: " + this.GetType().ToString() + "->" + ((object)MethodBase.GetCurrentMethod()).ToString() + " ;"); } #endif #endregion Access Log // creating a new StoreDataInfo will initialize LockDate to null (unlocked) SessionStoreDataContext data = new SessionStoreDataContext(item); Cache.Add(GetCacheKey(id), (object)SessionStoreDataContext.Serialize(data), DateTime.Now.AddMinutes(item.Timeout)); }
public override void CreateUninitializedItem(HttpContext context, string id, int timeout) { // 1 remote call #region Access Log #if TRACE { Handler.LogHandler.Tracking("Access Method: " + this.GetType().ToString() + "->" + ((object)MethodBase.GetCurrentMethod()).ToString() + " ;"); } #endif #endregion Access Log _timeout = timeout; SessionStoreDataContext data = new SessionStoreDataContext(CreateNewStoreData(context, timeout)); Cache.Add(GetCacheKey(id), (object)SessionStoreDataContext.Serialize(data), DateTime.Now.AddMinutes(data.Data.Timeout)); }
/// <summary> /// Deserializes binary data into a fully hydrated SessionStoreDataContext. /// </summary> /// <param name="bytes">serialized binary data</param> /// <returns>The object representation of the session data</returns> /// <exception cref="HttpException">Thrown if deserialization encounters a problem</exception> internal static SessionStoreDataContext Deserialize(byte[] bytes, HttpContext context) { try { using (MemoryStream stream = new MemoryStream(bytes)) { using (BinaryReader reader = new BinaryReader(stream)) { //See comments in Serialize method for description of fields int timeout = reader.ReadInt32(); bool hasItems = reader.ReadBoolean(); bool hasStaticObjects = reader.ReadBoolean(); bool isLocked = reader.ReadBoolean(); DateTime?lockDate = null; if (isLocked) { lockDate = DateTime.FromBinary(reader.ReadInt64()); } SessionStateItemCollection items = hasItems ? SessionStateItemCollection.Deserialize(reader) : new SessionStateItemCollection(); HttpStaticObjectsCollection staticObjects = hasStaticObjects ? HttpStaticObjectsCollection.Deserialize(reader) : SessionStateUtility.GetSessionStaticObjects(context); //this is a sanity byte. If it does not equal 0xFF, there is a problem if (reader.ReadByte() != 0xff) { throw new HttpException("Invalid Session State"); } SessionStoreDataContext data = new SessionStoreDataContext(new SessionStateStoreData(items, staticObjects, timeout)); data.LockDate = lockDate; return(data); } } } catch (EndOfStreamException) { throw new HttpException("Invalid Session State"); } }
public override void ReleaseItemExclusive(HttpContext context, string id, object lockId) { // 1-2 remote calls #region Access Log #if TRACE { Handler.LogHandler.Tracking("Access Method: " + this.GetType().ToString() + "->" + ((object)MethodBase.GetCurrentMethod()).ToString() + " ;"); } #endif #endregion Access Log //todo: replace with single unlock call when available byte[] bytes = Cache.Get <byte[]>(GetCacheKey(id)); if (bytes != null) { SessionStoreDataContext data = SessionStoreDataContext.Deserialize(bytes, context); data.ClearLock(); Cache.Add(GetCacheKey(id), (object)SessionStoreDataContext.Serialize(data), DateTime.Now.AddMinutes(data.Data.Timeout)); } }
/// <summary> /// Serializes a SessionStoreDataContext into binary data. /// </summary> /// <param name="info">The object to serialize</param> /// <returns>Binary data that can later be deserialized into a fully /// hydrated SessionStoreDataContext</returns> internal static byte[] Serialize(SessionStoreDataContext info) { using (MemoryStream stream = new MemoryStream()) { using (BinaryWriter writer = new BinaryWriter(stream)) { bool hasItems = info.Data.Items != null && info.Data.Items.Count > 0; bool hasStaticObjects = info.Data.StaticObjects != null && !info.Data.StaticObjects.NeverAccessed; bool isLocked = info.IsLocked; //Serialize timeout information writer.Write(info.Data.Timeout); //Serialize whether to bother reading SessionStateItemCollection data writer.Write(hasItems); //Serialize whether to bother reading HttpStaticObjectCollection data writer.Write(hasStaticObjects); //Serialize whether to bother reading a lock date writer.Write(isLocked); if (isLocked) { //Serialize numeric representation of DateTime object writer.Write(info.LockDate.Value.ToBinary()); } if (hasItems) { //Defer to the item collection class for serialization of collection ((SessionStateItemCollection)info.Data.Items).Serialize(writer); } if (hasStaticObjects) { //Defer to the static object collection class for serialization of collection info.Data.StaticObjects.Serialize(writer); } //Trailing byte helpful for sanity checks during deserialization writer.Write((byte)0xff); } return(stream.GetBuffer()); } }
private SessionStateStoreData FetchCachedStoreData(HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions, bool exclusive) { // 1-2 remote calls locked = false; lockAge = TimeSpan.Zero; lockId = null; actions = SessionStateActions.None; // check for existing session byte[] bytes = Cache.Get <byte[]>(GetCacheKey(id)); if (bytes == null) { return(null); } SessionStoreDataContext data = SessionStoreDataContext.Deserialize(bytes, context); locked = data.IsLocked; if (locked) { lockAge = DateTime.Now.Subtract(data.LockDate.Value); lockId = data.LockDate; // specs require null to be returned return(null); } //todo: rewrite with real locking when available // as of a few microseconds ago, this session was unlocked, so proceed if (exclusive) { data.LockDate = DateTime.Now; // not perfectly thread safe as there can be race conditions between // clustered servers, but this is the best we've got Cache.Add(GetCacheKey(id), (object)SessionStoreDataContext.Serialize(data), DateTime.Now.AddMinutes(data.Data.Timeout)); } return(data.Data); }