IGNITE-4186 .NET: Fix "Invalid session release request" exception in IgniteSessionStateStoreProvider.SetAndReleaseItemExclusive
This closes #1227 Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/884b2812 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/884b2812 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/884b2812 Branch: refs/heads/ignite-2693 Commit: 884b281218d88c028daab25d35c14ee2b41be36e Parents: 69487f2 Author: Pavel Tupitsyn <[email protected]> Authored: Thu Nov 10 20:35:15 2016 +0300 Committer: Pavel Tupitsyn <[email protected]> Committed: Thu Nov 10 20:38:07 2016 +0300 ---------------------------------------------------------------------- .../IgniteSessionStateStoreProviderTest.cs | 49 +++++++++++++++++--- .../IgniteSessionStateStoreProvider.cs | 21 ++++++--- 2 files changed, 57 insertions(+), 13 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/884b2812/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/IgniteSessionStateStoreProviderTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/IgniteSessionStateStoreProviderTest.cs b/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/IgniteSessionStateStoreProviderTest.cs index 9c3b07c..c6e3b30 100644 --- a/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/IgniteSessionStateStoreProviderTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.AspNet.Tests/IgniteSessionStateStoreProviderTest.cs @@ -209,6 +209,24 @@ namespace Apache.Ignite.AspNet.Tests Assert.AreEqual(TimeSpan.Zero, lockAge); Assert.AreEqual(SessionStateActions.None, actions); + // SetAndRelease with no lock. This happens with certain versions of ASP.NET. + var item = provider.CreateNewStoreData(HttpContext, 7); + // ReSharper disable once AssignNullToNotNullAttribute (lockId is not supposed to be null, but it can be). + provider.SetAndReleaseItemExclusive(HttpContext, Id, item, null, true); + + // Check added item. + res = provider.GetItem(HttpContext, Id, out locked, out lockAge, out lockId, out actions); + Assert.IsNotNull(res); + Assert.IsNull(lockId); + Assert.AreEqual(7, res.Timeout); + Assert.IsFalse(locked); + Assert.AreEqual(TimeSpan.Zero, lockAge); + Assert.AreEqual(SessionStateActions.None, actions); + + // Remove item. + // ReSharper disable once AssignNullToNotNullAttribute (lockId is not supposed to be null, but it can be). + provider.RemoveItem(HttpContext, Id, null, null); + // Add item. provider.CreateUninitializedItem(HttpContext, Id, 7); @@ -228,7 +246,7 @@ namespace Apache.Ignite.AspNet.Tests Assert.IsFalse(locked); Assert.AreEqual(TimeSpan.Zero, lockAge); Assert.AreEqual(SessionStateActions.None, actions); - provider.SetAndReleaseItemExclusive(HttpContext, Id, UpdateStoreData(res), lockId, true); + provider.SetAndReleaseItemExclusive(HttpContext, Id, UpdateStoreData(res), lockId, false); // Not locked, item present. res = provider.GetItem(HttpContext, Id, out locked, out lockAge, out lockId, out actions); @@ -331,20 +349,37 @@ namespace Apache.Ignite.AspNet.Tests Assert.IsFalse(GetProvider().SetItemExpireCallback(null)); // Check there is no item. - var res = provider.GetItem(HttpContext, "myId", out locked, out lockAge, out lockId, out actions); + var res = provider.GetItem(HttpContext, Id, out locked, out lockAge, out lockId, out actions); Assert.IsNull(res); - // Put an item. - provider.CreateUninitializedItem(HttpContext, "myId", 1); + // Put an item with CreateUninitializedItem and check. + provider.CreateUninitializedItem(HttpContext, Id, 1); + CheckExpiry(provider); + + // Put an item with SetAndReleaseItemExclusive and check. + var data = provider.CreateNewStoreData(HttpContext, 1); + provider.SetAndReleaseItemExclusive(HttpContext, Id, data, lockId, true); + CheckExpiry(provider); + } - // Check that it is there. - res = provider.GetItem(HttpContext, "myId", out locked, out lockAge, out lockId, out actions); + /// <summary> + /// Checks item expiration. + /// </summary> + private static void CheckExpiry(SessionStateStoreProviderBase provider) + { + bool locked; + TimeSpan lockAge; + object lockId; + SessionStateActions actions; + + // Check that item is present. + var res = provider.GetItem(HttpContext, Id, out locked, out lockAge, out lockId, out actions); Assert.IsNotNull(res); // Wait a minute and check again. Thread.Sleep(TimeSpan.FromMinutes(1.05)); - res = provider.GetItem(HttpContext, "myId", out locked, out lockAge, out lockId, out actions); + res = provider.GetItem(HttpContext, Id, out locked, out lockAge, out lockId, out actions); Assert.IsNull(res); } http://git-wip-us.apache.org/repos/asf/ignite/blob/884b2812/modules/platforms/dotnet/Apache.Ignite.AspNet/IgniteSessionStateStoreProvider.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.AspNet/IgniteSessionStateStoreProvider.cs b/modules/platforms/dotnet/Apache.Ignite.AspNet/IgniteSessionStateStoreProvider.cs index 86035dd..a5e8199 100644 --- a/modules/platforms/dotnet/Apache.Ignite.AspNet/IgniteSessionStateStoreProvider.cs +++ b/modules/platforms/dotnet/Apache.Ignite.AspNet/IgniteSessionStateStoreProvider.cs @@ -294,11 +294,20 @@ namespace Apache.Ignite.AspNet var data = (IgniteSessionStateStoreData) item; - if (!(lockId is long) || data.LockId != (long) lockId) - throw new IgniteException(string.Format(CultureInfo.InvariantCulture, - "Invalid session release request, expected lockId: {0}, actual: {1}", data.LockId, lockId)); + if (newItem) + { + var cache = _expiryCacheHolder.GetCacheWithExpiry(data.Timeout * 60); + + PutItem(key, data, cache); + } + else + { + if (!(lockId is long) || data.LockId != (long) lockId) + throw new IgniteException(string.Format(CultureInfo.InvariantCulture, + "Invalid session release request, expected lockId: {0}, actual: {1}", data.LockId, lockId)); - SetAndUnlockItem(key, data); + SetAndUnlockItem(key, data); + } } /// <summary> @@ -333,7 +342,7 @@ namespace Apache.Ignite.AspNet /// </summary> /// <param name="context">The <see cref="T:System.Web.HttpContext" /> for the current request.</param> /// <param name="timeout">The session-state <see cref="P:System.Web.SessionState.HttpSessionState.Timeout" /> - /// value for the new <see cref="T:System.Web.SessionState.SessionStateStoreData" />.</param> + /// value for the new <see cref="T:System.Web.SessionState.SessionStateStoreData" />, in minutes.</param> /// <returns> /// A new <see cref="T:System.Web.SessionState.SessionStateStoreData" /> for the current request. /// </returns> @@ -349,7 +358,7 @@ namespace Apache.Ignite.AspNet /// <param name="id">The <see cref="P:System.Web.SessionState.HttpSessionState.SessionID" /> /// for the current request.</param> /// <param name="timeout">The session <see cref="P:System.Web.SessionState.HttpSessionState.Timeout" /> - /// for the current request.</param> + /// for the current request, in minutes.</param> public override void CreateUninitializedItem(HttpContext context, string id, int timeout) { var cache = _expiryCacheHolder.GetCacheWithExpiry((long) timeout * 60);
