public void TestNonExclusiveReadFromSession() { bool locked; TimeSpan lockAge; object lockId; SessionStateActions actions; SessionStateStoreData data = m_store.GetItem(null, SESSION_ID, out locked, out lockAge, out lockId, out actions); Assert.IsFalse(locked); Assert.AreEqual(TimeSpan.Zero, lockAge); Assert.IsNull(lockId); Assert.AreEqual(SessionStateActions.None, actions); ISessionStateItemCollection session = data.Items; AssertSessionDefaults(session); }
public async Task SetAndReleaseItemExclusive_NewItemValidItems() { Utility.SetConfigUtilityToDefault(); string id = "session-id"; ChangeTrackingSessionStateItemCollection sessionStateItemCollection = Utility.GetChangeTrackingSessionStateItemCollection(); sessionStateItemCollection["session-key"] = "session-value"; SessionStateStoreData sssd = new SessionStateStoreData(sessionStateItemCollection, null, 15); var mockCache = A.Fake <ICacheConnection>(); RedisSessionStateProvider sessionStateStore = new Oriflame.Web.Redis.RedisSessionStateProvider(); sessionStateStore.cache = mockCache; await sessionStateStore.SetAndReleaseItemExclusiveAsync(FakeHttpContext, id, sssd, null, true, CancellationToken.None); A.CallTo(() => mockCache.Set(A <ISessionStateItemCollection> .That.Matches( o => o.Count == 1 && o["session-key"] != null ), 900)).MustHaveHappened(); }
public async Task SetAndReleaseItemExclusive_OldItemRemovedItems() { Utility.SetConfigUtilityToDefault(); string id = "session-id"; ChangeTrackingSessionStateItemCollection sessionStateItemCollection = Utility.GetChangeTrackingSessionStateItemCollection(); sessionStateItemCollection["session-key"] = "session-val"; sessionStateItemCollection.Remove("session-key"); SessionStateStoreData sssd = new SessionStateStoreData(sessionStateItemCollection, null, 15); var mockCache = A.Fake <ICacheConnection>(); RedisSessionStateProvider sessionStateStore = new Oriflame.Web.Redis.RedisSessionStateProvider(); sessionStateStore.cache = mockCache; await sessionStateStore.SetAndReleaseItemExclusiveAsync(FakeHttpContext, id, sssd, 7, false, CancellationToken.None); A.CallTo(() => mockCache.TryUpdateAndReleaseLock(A <object> .Ignored, A <ChangeTrackingSessionStateItemCollection> .That.Matches(o => o.Count == 0 && o.GetModifiedKeys().Count == 0 && o.GetDeletedKeys().Count == 1), 900)).MustHaveHappened(); }
public void TestExternalAttributeReplacement() { bool locked; TimeSpan lockAge; object lockId; SessionStateActions actions; SessionStateStoreData data = m_store.GetItemExclusive(null, SESSION_ID, out locked, out lockAge, out lockId, out actions); // replace "large" external attribute with a "small" attribute ISessionStateItemCollection session = data.Items; session["blob"] = CreateBlob(1); m_store.SetAndReleaseItemExclusive(null, SESSION_ID, data, lockId, false); Assert.AreEqual(0, m_extAttrCache.Count); }
/// <summary> /// Form a hashtable to be added to cache /// </summary> /// <param name="context"></param> /// <param name="data"></param> /// <param name="flag"></param> /// <param name="timeout"></param> /// <returns></returns> private Hashtable InsertContents(HttpContext context, SessionStateStoreData data, SessionStateActions flag, int timeout) { Hashtable items = new Hashtable(4); if (data != null) { byte[] buffer = SessionSerializationUtil.Serialize(data); items.Add(SESSION_DATA, buffer); items.Add(TIMEOUT_KEY, (int)data.Timeout); } else { items.Add(TIMEOUT_KEY, (int)timeout); } items.Add(ACTIONS_KEY, flag); return(items); }
public void TestExternalAttributeReadBeforeWrite() { bool locked; TimeSpan lockAge; object lockId; SessionStateActions actions; SessionStateStoreData data = m_store.GetItemExclusive(null, SESSION_ID, out locked, out lockAge, out lockId, out actions); ISessionStateItemCollection session = data.Items; var blob = session["blob"]; session["blob"] = CreateBlob(1); m_store.SetAndReleaseItemExclusive(null, SESSION_ID, data, lockId, false); Assert.AreEqual(0, m_extAttrCache.Count); }
public void GetItemExclusiveCreatesLock() { _cacheImpl.Setup(cache => cache.Get <byte[]>("Session(THIS_IS_MY_ID, UnitTest)")).Returns(new byte[] { 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF }); _cacheImpl.Setup(cache => cache.Add("Session(THIS_IS_MY_ID, UnitTest)", (object)It.Is <byte[]>(bytes => bytes[6] == 0x01), It.IsInRange(DateTime.Now.AddMinutes(19), DateTime.Now.AddMinutes(21), Range.Inclusive))); bool locked; TimeSpan lockAge; object lockId; SessionStateActions actions; SessionStateStoreData data = _provider.GetItemExclusive(_context, "THIS_IS_MY_ID", out locked, out lockAge, out lockId, out actions); _cacheImpl.VerifyAll(); Assert.IsNotNull(data); Assert.IsFalse(locked); Assert.AreEqual(TimeSpan.Zero, lockAge); Assert.AreEqual(SessionStateActions.None, actions); }
/// <summary> /// Updates the session-item information in the session-state data store with values from the current request, and clears the lock on the data. /// </summary> /// <param name="context">The HttpContext for the current request.</param> /// <param name="sessionId">The session identifier for the current request.</param> /// <param name="item">The SessionStateStoreData object that contains the current session values to be stored.</param> /// <param name="lockId">The lock identifier for the current request.</param> /// <param name="newItem">true to identify the session item as a new item; false to identify the session item as an existing item.</param> public override void SetAndReleaseItemExclusive(HttpContext context, string sessionId, SessionStateStoreData item, object lockId, bool newItem) { LogInfo("SetAndReleaseItemExclusive", sessionId, lockId, newItem, context); string serialized = serialize(item.Items as SessionStateItemCollection); Document newValues = new Document(); newValues[ATTRIBUTE_SESSION_ID] = GetHashKey(sessionId); newValues[ATTRIBUTE_LOCKED] = false; newValues[ATTRIBUTE_LOCK_ID] = null; newValues[ATTRIBUTE_LOCK_DATE] = DateTime.Now; newValues[ATTRIBUTE_EXPIRES] = DateTime.Now.Add(this._timeout); newValues[ATTRIBUTE_FLAGS] = 0; newValues[ATTRIBUTE_SESSION_ITEMS] = serialized; newValues[ATTRIBUTE_RECORD_FORMAT_VERSION] = CURRENT_RECORD_FORMAT_VERSION; if (newItem) { newValues[ATTRIBUTE_CREATE_DATE] = DateTime.Now; this._table.PutItem(newValues); } else { Document expected = new Document(); expected[ATTRIBUTE_LOCK_ID] = lockId.ToString(); // Not really any reason the condition should fail unless we get in some sort of weird // app pool reset mode. try { this._table.UpdateItem(newValues, new UpdateItemOperationConfig() { Expected = expected }); } catch (ConditionalCheckFailedException) { LogInfo("(SetAndReleaseItemExclusive) Conditional check failed for update.", sessionId, context); } } }
/// <inheritdoc /> public override async Task SetAndReleaseItemExclusiveAsync( HttpContextBase context, string id, SessionStateStoreData item, object lockId, bool newItem, CancellationToken cancellationToken) { byte[] buf; int length; int lockCookie; if (item == null) { throw new ArgumentNullException("item"); } if (id == null) { throw new ArgumentNullException("id"); } if (id.Length > SessionIDManager.SessionIDMaxLength) { throw new ArgumentException(SR.Session_id_too_long); } id = AppendAppIdHash(id); try { SerializeStoreData(item, SqlSessionStateRepositoryUtil.DefaultItemLength, out buf, out length, s_compressionEnabled); } catch { if (!newItem) { await ReleaseItemExclusiveAsync(context, id, lockId, cancellationToken); } throw; } lockCookie = lockId == null ? 0 : (int)lockId; await s_sqlSessionStateRepository.CreateOrUpdateSessionStateItemAsync(newItem, id, buf, length, item.Timeout, lockCookie, _rqOrigStreamLen); }
public void TestSessionModification() { bool locked; TimeSpan lockAge; object lockId; SessionStateActions actions; SessionStateStoreData data = m_store.GetItemExclusive(null, SESSION_ID, out locked, out lockAge, out lockId, out actions); Assert.IsTrue(locked); Assert.IsTrue(lockAge >= TimeSpan.Zero); Assert.IsNotNull(lockId); Assert.AreEqual(SessionStateActions.None, actions); ISessionStateItemCollection session = data.Items; AssertSessionDefaults(session); session["int"] = 2; session["string"] = "modified string"; session["date"] = DateTime.Now; session["bool"] = true; session["blob"] = CreateBlob(1024); session["person"] = new PortablePerson("Novak Seovic", new DateTime(2007, 12, 28)); m_store.SetAndReleaseItemExclusive(null, SESSION_ID, data, lockId, false); data = m_store.GetItem(null, SESSION_ID, out locked, out lockAge, out lockId, out actions); Assert.IsFalse(locked); Assert.AreEqual(TimeSpan.Zero, lockAge); Assert.IsNull(lockId); Assert.AreEqual(SessionStateActions.None, actions); session = data.Items; Assert.AreEqual(2, session["int"]); Assert.AreEqual("modified string", session["string"]); Assert.AreNotEqual(DateTime.Today, session["date"]); Assert.AreEqual(true, session["bool"]); Assert.AreNotEqual(BLOB, session["blob"]); Assert.AreNotEqual(PERSON, session["person"]); }
/// <summary> /// SessionStateProviderBase.SetAndReleaseItemExclusive /// </summary> public override void SetAndReleaseItemExclusive( HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem) { BsonArray arraySession = MongoSessionStateStoreHelpers.Serialize(item); MongoClient conn = GetConnection(); var sessionCollection = GetSessionCollection(conn); if (newItem) { var insertDoc = MongoSessionStateStoreHelpers.GetNewBsonSessionDocument( id: id, applicationName: ApplicationName, created: DateTime.Now.ToUniversalTime(), lockDate: DateTime.Now.ToUniversalTime(), lockId: 0, timeout: item.Timeout, locked: false, jsonSessionItemsArray: arraySession, flags: 0); this.UpsertEntireSessionDocument(sessionCollection, insertDoc); } else { var filter = Builders <BsonDocument> .Filter.And( Builders <BsonDocument> .Filter.Eq("_id", MongoSessionStateStoreHelpers.GetDocumentSessionId(id, ApplicationName)), Builders <BsonDocument> .Filter.Eq("LockId", (Int32)lockId) ); var update = Builders <BsonDocument> .Update .Set("Expires", DateTime.Now.AddMinutes(item.Timeout).ToUniversalTime()) .Set("SessionItemJSON", arraySession) .Set("Locked", false); this.UpdateSessionCollection(sessionCollection, filter, update); } }
/// <summary> /// Updates the session-item information in the session-state data store with values /// from the current request, and clears the lock on the data /// </summary> /// <param name="context">HttpContext for the current request</param> /// <param name="id">Session ID for the session</param> /// <param name="item">The session state item to be stored</param> /// <param name="lockId">The lock identifier for the current request</param> /// <param name="newItem">True if this is a new session item, false if it is an existing item</param> public override void SetAndReleaseItemExclusive( HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem) { SessionStateItem e; do { if (!newItem) { var tmp = (ulong)lockId; // Load the entire item with CAS (need the DataCas value also for the save) e = SessionStateItem.Load(_bucket, id, false); // if we're expecting an existing item, but // it's not in the cache // or it's locked by someone else, then quit if (e == null || e.LockId != tmp) { return; } } else { // Create a new item if it requested e = new SessionStateItem(); } // Set the new data and reset the locks e.Timeout = item.Timeout; e.Data = (SessionStateItemCollection)item.Items; e.Flag = SessionStateActions.None; e.LockId = 0; e.LockTime = DateTime.MinValue; // Attempt to save with CAS and loop around if it fails } while (!e.SaveAll(_bucket, id, _exclusiveAccess && !newItem)); }
/// <inheritdoc /> public override async Task RemoveItemAsync( HttpContextBase context, string id, object lockId, SessionStateStoreData item, CancellationToken cancellationToken) { if (id == null) { throw new ArgumentNullException("id"); } if (id.Length > SessionIDManager.SessionIDMaxLength) { throw new ArgumentException(Resource1.Session_id_too_long); } id = AppendAppIdHash(id); await s_sqlSessionStateRepository.RemoveSessionItemAsync(id, lockId); }
private static void SerializeSessionStateStoreData( SessionStateStoreData item, int initialStreamSize, out byte[] buffer, out int length) { MemoryStream memoryStream = (MemoryStream)null; try { memoryStream = new MemoryStream(initialStreamSize); OracleSessionStateStore.Serialize(item, (Stream)memoryStream); buffer = memoryStream.GetBuffer(); length = (int)memoryStream.Length; } finally { memoryStream?.Dispose(); } }
/// <inheritdoc /> public override Task RemoveItemAsync( HttpContextBase context, string id, object lockId, SessionStateStoreData item, CancellationToken cancellationToken) { if (id == null) { throw new ArgumentNullException("id"); } if (id.Length > SessionIDManager.SessionIDMaxLength) { throw new ArgumentException(SR.Session_id_too_long); } s_store.Remove(id); return(Task.CompletedTask); }
public static byte[] Serialize(SessionStateStoreData sessionData) { byte sessionFlag = 0; MemoryStream stream = null; byte[] buffer = null; try { stream = new MemoryStream(); BinaryWriter writer = new BinaryWriter(stream); if (sessionData.Items != null) { sessionFlag = (byte)(sessionFlag | SESSION_ITEMS); } if (sessionData.StaticObjects != null && !sessionData.StaticObjects.NeverAccessed) { sessionFlag = (byte)(sessionFlag | SESSION_STATIC_ITEMS); } writer.Write(sessionFlag); if ((byte)(sessionFlag & SESSION_ITEMS) == SESSION_ITEMS) { ((SessionStateItemCollection)sessionData.Items).Serialize(writer); } if ((byte)(sessionFlag & SESSION_STATIC_ITEMS) == SESSION_STATIC_ITEMS) { sessionData.StaticObjects.Serialize(writer); } writer.Write(sessionData.Timeout); } finally { if (stream != null) { buffer = stream.ToArray(); stream.Close(); } } return(buffer); }
public byte[] Serialize(SessionStateStoreData sessionState) { var hasItems = sessionState.Items != null && sessionState.Items.Count > 0; var hasStaticObjects = sessionState.StaticObjects != null && !sessionState.StaticObjects.NeverAccessed; var stream = new MemoryStream(); var writer = new BinaryWriter(stream); writer.Write(sessionState.Timeout); writer.Write(hasItems); writer.Write(hasStaticObjects); if (hasItems) { ((SessionStateItemCollection)sessionState.Items).Serialize(writer); } if (hasStaticObjects) { sessionState.StaticObjects.Serialize(writer); } writer.Write(byte.MaxValue); return(stream.ToArray()); }
/// <summary> /// Updates the store data. /// </summary> private static SessionStateStoreData UpdateStoreData(SessionStateStoreData data) { data.Timeout = 8; data.Items["name1"] = 1; data.Items["name2"] = "2"; var statics = data.StaticObjects; // Modification method is internal. var method = statics.GetType() .GetMethod("Add", BindingFlags.Instance | BindingFlags.NonPublic); Debug.Assert(method != null); method.Invoke(statics, new object[] { "int", typeof(int), false }); CheckStoreData(data); return(data); }
public override SessionStateStoreData GetItem(HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { // set default out parameters locked = false; lockAge = new TimeSpan(); lockId = null; actions = SessionStateActions.None; // try to get the session from cache. string sessionString = cache.GetAsync <string>(id).Result; if (string.IsNullOrEmpty(sessionString)) { return(null); } var sessionItems = JsonConvert.DeserializeObject <SessionStateItemCollection>(sessionString); var data = new SessionStateStoreData(sessionItems, null, 60); // todo: set timeout. return(data); }
public void RemoveLockedItemWithNullLockNotRemovesSession() { string sessionId = GenerateKey(); SessionStateStoreProvider provider = CreateProvider(); bool locked; TimeSpan lockAge; object lockId, lockId2; SessionStateActions actions; provider.CreateUninitializedItem(null, sessionId, SessionTimeoutInMinutesFromConfig); SessionStateStoreData storeData = provider.GetItemExclusive(null, sessionId, out locked, out lockAge, out lockId, out actions); provider.RemoveItem(null, sessionId, null, storeData); Thread.Sleep(100); storeData = provider.GetItem(null, sessionId, out locked, out lockAge, out lockId2, out actions); AssertSessionIsLocked(storeData, locked, lockAge, lockId, lockId2, actions); }
public void TestExternalAttributeReplaceSmall() { CheckCacheIsReady(); bool locked; TimeSpan lockAge; object lockId; SessionStateActions actions; SessionStateStoreData data = m_store.GetItemExclusive(null, SESSION_ID, out locked, out lockAge, out lockId, out actions); ISessionStateItemCollection session = data.Items; session["blob"] = CreateBlob(1); session["person"] = CreateBlob(1024); m_store.SetAndReleaseItemExclusive(null, SESSION_ID, data, lockId, false); Assert.AreEqual(1, m_extAttrCache.Count); }
public async void SetAndReleaseItemExclusiveAsync_Should_Release_NonExclsive_SessionItem() { var provider = CreateProvider(); provider.Initialize(DefaultProviderName, CreateSessionStateProviderConfig(), CreateSessionStateSection(), createConnectionStringSettings()); var sessionCollection = new SessionStateItemCollection(); var now = DateTime.UtcNow; sessionCollection["test1"] = "test1"; sessionCollection["test2"] = now; var data = new SessionStateStoreData(sessionCollection, new HttpStaticObjectsCollection(), TestTimeout); byte[] buff; int length; SqlSessionStateProviderAsync.SerializeStoreData(data, DefaultItemLength, out buff, out length, false); var repoMoq = new Mock <ISqlSessionStateRepository>(); var ssItem = new SessionItem(buff, false, TimeSpan.Zero, null, SessionStateActions.None); repoMoq.Setup(repo => repo.GetSessionStateItemAsync(SqlSessionStateProviderAsync.AppendAppIdHash(TestSessionId), false)) .Returns(Task.FromResult(ssItem)); provider.SqlSessionStateRepository = repoMoq.Object; var httpContext = CreateMoqHttpContextBase(); var getItemResult = await provider.GetItemAsync(httpContext, TestSessionId, CancellationToken.None); var sessionReleased = false; repoMoq.Setup(repo => repo.CreateOrUpdateSessionStateItemAsync(false, SqlSessionStateProviderAsync.AppendAppIdHash(TestSessionId), buff, length, TestTimeout, 0, provider.OrigStreamLen)) .Returns(Task.CompletedTask) .Callback(() => sessionReleased = true); await provider.SetAndReleaseItemExclusiveAsync(httpContext, TestSessionId, getItemResult.Item, null, false, CancellationToken.None); Assert.True(sessionReleased); }
public void GetItem_RecordFound() { Utility.SetConfigUtilityToDefault(); string id = "session-id"; bool locked; TimeSpan lockAge; object lockId = null; SessionStateActions actions; ISessionStateItemCollection sessionStateItemCollection = new ChangeTrackingSessionStateItemCollection(); sessionStateItemCollection["session-key"] = "session-value"; sessionStateItemCollection["SessionStateActions"] = SessionStateActions.None; SessionStateStoreData sssd = new SessionStateStoreData(sessionStateItemCollection, null, 15); ISessionStateItemCollection sessionData = new ChangeTrackingSessionStateItemCollection(); sessionData["session-key"] = "session-value"; sessionData["SessionStateActions"] = SessionStateActions.None; ISessionStateItemCollection mockSessionData = null; object mockLockId = 0; int mockSessionTimeout; int sessionTimeout = (int)RedisSessionStateProvider.configuration.SessionTimeout.TotalMinutes; var mockCache = A.Fake <ICacheConnection>(); A.CallTo(() => mockCache.TryCheckWriteLockAndGetData(out mockLockId, out mockSessionData, out mockSessionTimeout)).Returns(true).AssignsOutAndRefParameters(0, sessionData, (int)RedisSessionStateProvider.configuration.SessionTimeout.TotalMinutes); RedisSessionStateProvider sessionStateStore = new RedisSessionStateProvider(); sessionStateStore.cache = mockCache; SessionStateStoreData sessionStateStoreData = sessionStateStore.GetItem(null, id, out locked, out lockAge, out lockId, out actions); A.CallTo(() => mockCache.TryCheckWriteLockAndGetData(out mockLockId, out sessionData, out sessionTimeout)).MustHaveHappened(); Assert.Equal(true, Utility.CompareSessionStateStoreData(sessionStateStoreData, sssd)); Assert.Equal(false, locked); Assert.Equal(TimeSpan.Zero, lockAge); Assert.Equal(actions, SessionStateActions.None); }
public override void SetAndReleaseItemExclusive(HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem) { var redis = GetRedisConnection(); var getLock = redis.Hashes.Get(0, lockHashKey, id); var lockIdAsBytes = (byte[])lockId; var ms = new MemoryStream(); var writer = new BinaryWriter(ms); if (item.Items as SessionStateItemCollection != null) { ((SessionStateItemCollection)item.Items).Serialize(writer); } writer.Close(); byte[] sessionData = ms.ToArray(); var sessionItemHash = new Dictionary <string, byte[]>(); sessionItemHash.Add("initialize", new byte[] { 0 }); sessionItemHash.Add("data", sessionData); sessionItemHash.Add("timeoutMinutes", BitConverter.GetBytes(item.Timeout)); LockData lockData; getLock.Wait(); if (getLock.Result == null) { redis.Hashes.Set(0, GetKeyForSessionId(id), sessionItemHash, false); } else if (LockData.TryParse(getLock.Result, out lockData) && Enumerable.SequenceEqual(lockData.LockId, lockIdAsBytes)) { redis.Hashes.Set(0, GetKeyForSessionId(id), sessionItemHash, false); redis.Hashes.Remove(0, lockHashKey, id); } }
private static void AssertGotSession(SessionStateStoreData storeData, bool locked, TimeSpan lockAge, object lockId, bool exclusive = false, object originalLock = null) { Assert.IsNotNull(storeData); Assert.IsFalse(locked); Assert.AreEqual(TimeSpan.Zero, lockAge); if (exclusive) { if (originalLock == null) { Assert.IsNotNull(lockId); } else { Assert.AreEqual(originalLock, lockId); } } else { Assert.IsNull(lockId); } }
public void SessionWriteCycle_Valid() { using (RedisServer redisServer = new RedisServer()) { string sessionId = ResetRedisConnectionWrapperAndConfiguration(); // Inserting empty session with "SessionStateActions.InitializeItem" flag into redis server RedisSessionStateProvider ssp = new RedisSessionStateProvider(); ssp.CreateUninitializedItem(null, sessionId, (int)RedisSessionStateProvider.configuration.SessionTimeout.TotalMinutes); // Get write lock and session from cache bool locked; TimeSpan lockAge; object lockId; SessionStateActions actions; SessionStateStoreData storeData = ssp.GetItemExclusive(null, sessionId, out locked, out lockAge, out lockId, out actions); // Get actual connection and varify lock and session timeout IDatabase actualConnection = GetRealRedisConnection(); Assert.Equal(lockId.ToString(), actualConnection.StringGet(ssp.cache.Keys.LockKey).ToString()); Assert.Equal(((int)RedisSessionStateProvider.configuration.SessionTimeout.TotalSeconds).ToString(), actualConnection.HashGet(ssp.cache.Keys.InternalKey, "SessionTimeout").ToString()); // setting data as done by any normal session operation storeData.Items["key"] = "value"; // session update ssp.SetAndReleaseItemExclusive(null, sessionId, storeData, lockId, false); Assert.Equal(1, actualConnection.HashGetAll(ssp.cache.Keys.DataKey).Length); // reset sessions timoue ssp.ResetItemTimeout(null, sessionId); // End request ssp.EndRequest(null); // remove data and lock from redis DisposeRedisConnectionWrapper(); } }
/// <summary> /// 设置并释放项 /// </summary> /// <param name="context"></param> /// <param name="id"></param> /// <param name="item"></param> /// <param name="lockId"></param> /// <param name="newItem"></param> public void SetAndReleaseItem(System.Web.HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem) { MongoDBSessionDo session; if (newItem) { //删除过期的会话信息 collection.Remove(Query.And(Query.EQ("_id", id), Query.LT("Expired", DateTime.Now))); //插入新的会话信息 session = new MongoDBSessionDo() { SessionId = id, Created = DateTime.Now, Expired = DateTime.Now.AddMinutes(sessionStateSection.Timeout.TotalMinutes), LockDate = DateTime.Now, LockId = 0, Locked = false, TimeOut = item.Timeout, SessionItem = Serialize((SessionStateItemCollection)item.Items), Flags = (Int32)SessionStateActions.None }; collection.Save(session); } else { //更新会话信息 var query = Query.And(Query.EQ("_id", id), Query.EQ("LockId", (Int32)lockId)); session = collection.FindOne(query); session.Expired = DateTime.Now.AddMinutes(item.Timeout); session.SessionItem = Serialize((SessionStateItemCollection)item.Items); session.Locked = false; var update = Update.Set("Expired", DateTime.Now.AddMinutes(item.Timeout)) .Set("SessionItem", Serialize((SessionStateItemCollection)item.Items)) .Set("Locked", false); collection.Update(query, update); } }
public override void RemoveItem(System.Web.HttpContext context, string id, object lockId, SessionStateStoreData item) { var query = Query.And(Query.EQ("_id", id), Query.EQ("App", ApplicationName), Query.EQ("LockId", (Int32)lockId)); try { MongoCollection sessionCollection = GetSessionCollection(); sessionCollection.Remove(query, writeMode); } catch (Exception e) { if (WriteExceptionsToEventLog) { WriteToEventLog(e, "RemoveItem"); throw new ProviderException(ExceptionMessage); } throw; } }
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); } }); }
private SessionStateStoreData DoGet(HttpContext context, string id, bool exclusive, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actionFlags) { locked = false; lockId = null; lockAge = TimeSpan.Zero; actionFlags = SessionStateActions.None; SessionStateStoreData data = null; // 优先从缓存中读取Session数据 if (Initializer.Is64Bit) { // TODO: 这里可能会有一个缺陷! // 假设场景:一个用户有多个并发的请求在服务端同时执行,此时获取到的是同一个Session引用对象,可能会有并发读写问题! // 要解决这个问题,需要做对象的克隆,会浪费一些性能, // 然则考虑到现实情况,人工点击的操作频率,是不大可能出现线程并发问题的,所以这里暂且不处理。 data = _cacheStore.DoGet(context, id); if (data != null) { // 即使缓存中存在Session数据,也要更新Session数据文件的【最后访问时间】,供后面文件加载时判断是否过期 FileStore.SetLastAccessTime(id, DateTime.Now); return(data); } } // 缓存中如果不存在,有可能是AP.NET进程重启了,此时要从文件中读取Session数据 // 读到结果后,再存入缓存,供后续请求使用 data = _fileStore.DoGet(context, id, true); if (data != null) { _cacheStore.InsertCacheById(id, data); } return(data); }
} // End of the SetItemExpireCallback method /// <summary> /// Set and realease a session post /// </summary> public override void SetAndReleaseItemExclusive(HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem) { // Serialize the SessionStateItemCollection as a string. string sessItems = Serialize((SessionStateItemCollection)item.Items); // Create a webshop session WebshopSession webshopSession = new WebshopSession(); webshopSession.id = id; webshopSession.application_name = this.applicationName; webshopSession.created_date = DateTime.UtcNow; webshopSession.expires_date = DateTime.UtcNow.AddMinutes((Double)item.Timeout); webshopSession.lock_date = DateTime.UtcNow; webshopSession.lock_id = 0; webshopSession.timeout_limit = item.Timeout; webshopSession.locked = false; webshopSession.session_items = sessItems; webshopSession.flags = 0; if (newItem == true) { // Delete the session if it exists WebshopSession.DeleteOnId(id, this.applicationName); // Add the session WebshopSession.Add(webshopSession); } else { // Update session values webshopSession.lock_id = (Int32)lockId; // Update the session WebshopSession.UpdateWithLockId(webshopSession); } } // End of the SetAndReleaseItemExclusive method
/// <summary> /// This method removes the specified session item from the database /// </summary> /// <param name="context">The HttpContext object for the current request</param> /// <param name="id">The session ID for the current request</param> /// <param name="lockId">The lock identifier for the current request.</param> /// <param name="item">The session item to remove from the database.</param> public override void RemoveItem(System.Web.HttpContext context, string id, object lockId, SessionStateStoreData item) { try { using (MySqlConnection conn = new MySqlConnection(connectionString)) { MySqlCommand cmd = new MySqlCommand("DELETE FROM my_aspnet_sessions " + " WHERE SessionId = @SessionId AND ApplicationId = @ApplicationId AND LockId = @LockId", conn); cmd.Parameters.AddWithValue("@SessionId", id); cmd.Parameters.AddWithValue("@ApplicationId", ApplicationKey); cmd.Parameters.AddWithValue("@LockId", lockId); conn.Open(); cmd.ExecuteNonQuery(); } } catch (MySqlException e) { HandleMySqlException(e, "RemoveItem"); } }
/// <summary> /// This method updates the session time information in the database with the specified session item, /// and releases the lock. /// </summary> /// <param name="context">The HttpContext object for the current request</param> /// <param name="id">The session ID for the current request</param> /// <param name="item">The session item containing new values to update the session item in the database with. /// </param> /// <param name="lockId">The lock identifier for the current request.</param> /// <param name="newItem">A Boolean value that indicates whether or not the session item is new in the database. /// A false value indicates an existing item. /// </param> public override void SetAndReleaseItemExclusive(System.Web.HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem) { try { using (MySqlConnection conn = new MySqlConnection(connectionString)) { // Serialize the SessionStateItemCollection as a byte array byte[] sessItems = Serialize((SessionStateItemCollection)item.Items); MySqlCommand cmd; if (newItem) { //Insert the new session item . If there was expired session //with the same SessionId and Application id, it will be removed cmd = new MySqlCommand( "REPLACE INTO my_aspnet_sessions (SessionId, ApplicationId, Created, Expires," + " LockDate, LockId, Timeout, Locked, SessionItems, Flags)" + " Values(@SessionId, @ApplicationId, NOW(), NOW() + INTERVAL @Timeout MINUTE, NOW()," + " @LockId , @Timeout, @Locked, @SessionItems, @Flags)", conn); cmd.Parameters.AddWithValue("@SessionId", id); cmd.Parameters.AddWithValue("@ApplicationId", ApplicationKey); cmd.Parameters.AddWithValue("@Timeout", item.Timeout); cmd.Parameters.AddWithValue("@LockId", 0); cmd.Parameters.AddWithValue("@Locked", 0); cmd.Parameters.AddWithValue("@SessionItems", sessItems); cmd.Parameters.AddWithValue("@Flags", 0); } else { //Update the existing session item. cmd = new MySqlCommand( "UPDATE my_aspnet_sessions SET Expires = NOW() + INTERVAL @Timeout MINUTE," + " SessionItems = @SessionItems, Locked = @Locked " + " WHERE SessionId = @SessionId AND ApplicationId = @ApplicationId AND LockId = @LockId", conn); cmd.Parameters.AddWithValue("@Timeout", item.Timeout); cmd.Parameters.AddWithValue("@SessionItems", sessItems); cmd.Parameters.AddWithValue("@Locked", 0); cmd.Parameters.AddWithValue("@SessionId", id); cmd.Parameters.AddWithValue("@ApplicationId", ApplicationKey); cmd.Parameters.AddWithValue("@LockId", lockId); } conn.Open(); cmd.ExecuteNonQuery(); } } catch (MySqlException e) { HandleMySqlException(e, "SetAndReleaseItemExclusive"); } }
public abstract virtual void RemoveItem(System.Web.HttpContext context, string id, object lockId, SessionStateStoreData item) { }
/// <summary> /// Updates a locked session and releases the lock. /// </summary> /// <param name="context">The current request's HttpContext.</param> /// <param name="id">The session id for the current request.</param> /// <param name="item">The SessionStateStoreData object that contains the current session values to be stored.</param> /// <param name="lockId">The lock id for the current request.</param> /// <param name="newItem">Whether this is a new item or not.</param> public override void SetAndReleaseItemExclusive(HttpContext context, String id, SessionStateStoreData item, object lockId, bool newItem) { // Set session client.Set(GetSessionHash(id), Serialize((SessionStateItemCollection)item.Items), sessionConfig.Timeout); // Remove lock (no longer exclusive) client.Delete(GetSessionLockHash(id)); }
/// <summary> /// Deletes a session. /// </summary> /// <param name="context">The current request's HttpContext.</param> /// <param name="id">The session id for the current request.</param> /// <param name="lockId">The lock id for the current request.</param> /// <param name="item">The SessionStateStoreData to be removed.</param> /// <remarks>The SessionStateStoreData is not used in this case since we use the session id to generate the Memcached key.</remarks> public override void RemoveItem(HttpContext context, String id, object lockId, SessionStateStoreData item) { client.Delete(GetSessionHash(id)); // Notice we're not removing the lock here even though // we should, but since session ids are unique there's no reason // to waste time waiting for the delete to finish. // If you want to delete the lock object anyway uncomment the line below //client.Delete(GetSessionLockHash(id)); }
public abstract virtual void SetAndReleaseItemExclusive(System.Web.HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem) { }
} // End of the Deserialize method #endregion #region Delete methods /// <summary> /// Remove a session item /// </summary> public override void RemoveItem(HttpContext context, string id, object lockId, SessionStateStoreData item) { // Delete the session post WebshopSession.DeleteOnId(id, this.applicationName, (int)lockId); } // End of the RemoveItem method