MongoDB.Web.Providers.MongoDBSessionStateProvider.SetAndReleaseItemExclusive C# (CSharp) Method

SetAndReleaseItemExclusive() public method

public SetAndReleaseItemExclusive ( HttpContext context, string id, System.Web.SessionState.SessionStateStoreData item, object lockId, bool newItem ) : void
context System.Web.HttpContext
id string
item System.Web.SessionState.SessionStateStoreData
lockId object
newItem bool
return void
        public override void SetAndReleaseItemExclusive(HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem)
        {
            using (var memoryStream = new MemoryStream())
            {
                using (var binaryWriter = new BinaryWriter(memoryStream))
                {
                    ((SessionStateItemCollection)item.Items).Serialize(binaryWriter);

                    if (newItem)
                    {
                        var query = Query.And(Query.EQ("applicationVirtualPath", HostingEnvironment.ApplicationVirtualPath), Query.EQ("id", id));
                        this.mongoCollection.Remove(query);

                        var bsonDocument = new BsonDocument
                        {
                            { "applicationVirtualPath", HostingEnvironment.ApplicationVirtualPath },
                            { "created", DateTime.Now },
                            { "expires", DateTime.Now.AddMinutes(item.Timeout) },
                            { "id", id },
                            { "lockDate", DateTime.Now },
                            { "locked", false },
                            { "lockId", 0 },
                            { "sessionStateActions", SessionStateActions.None },
                            { "sessionStateItems", memoryStream.ToArray() },
                            { "sessionStateItemsCount", item.Items.Count },
                            { "timeout", item.Timeout }
                        };

                        this.mongoCollection.Insert(bsonDocument);
                    }
                    else
                    {
                        var query = Query.And(Query.EQ("applicationVirtualPath", HostingEnvironment.ApplicationVirtualPath), Query.EQ("id", id), Query.EQ("lockId", lockId.ToString()));
                        var upate = Update.Set("expires", DateTime.Now.Add(this.sessionStateSection.Timeout)).Set("items", memoryStream.ToArray()).Set("locked", false).Set("sessionStateItemsCount", item.Items.Count);
                        this.mongoCollection.Update(query, upate);
                    }
                }
            }
        }

Usage Example

Ejemplo n.º 1
0
		/// <summary>
		/// Creates sessions concurrently and stores a random binary blob in each session.  This
		/// method then waits for all the sessions to expire and verifies that each session has in
		/// fact been removed from the provider and the provider's memory cache.  It also takes a
		/// snapshot of the memory usage pre session creation, post session creation and post
		/// session expiration.  This method will fail is any session still exists in the provider
		/// or there was excessive memory usage.
		/// </summary>
		/// <param name="provider">The MongoDB provider to use for the test.</param>
		/// <param name="numberOfSessions">The number of sessions to create concurrently.</param>
		/// <param name="sessionSizeInMegabytes">The number of MB of buffer to create and store in each session.</param>
		private void CreateConcurrentSessionObjects(MongoDBSessionStateProvider provider, int numberOfSessions, byte sessionSizeInMegabytes)
		{
			var sessions = new System.Collections.Generic.SynchronizedCollection<string>();
			double initialWorkingSet, postSessionCreationWorkingSet, postSessionExpirationWorkingSet;

			var currentProcess = System.Diagnostics.Process.GetCurrentProcess();
			initialWorkingSet = (currentProcess.WorkingSet64 / 1024.0 / 1000.0);

			int sessionSize = (sessionSizeInMegabytes * 1024 * 1024);
			var result = Parallel.For(0, numberOfSessions, idx =>
			{
				System.Threading.Thread.Sleep(50); // Give a little wiggle room

				HttpRequest request = null;
				HttpResponse response = null;
				HttpContext context = GetContext(out request, out response);

				string sessionId = _SessionIdManager.CreateSessionID(context);
				sessions.Add(sessionId);

				byte[] dummyData = new byte[sessionSize];
				(new Random()).NextBytes(dummyData);

				var dataStore = provider.CreateNewStoreData(context, (_TimeoutInSeconds / 60));
				dataStore.Items["Data"] = dummyData;
				provider.SetAndReleaseItemExclusive(context, sessionId, dataStore, null, true);

				TestContext.WriteLine("Created session {0} with dummy data", sessionId);
			});

			while (!result.IsCompleted)
			{
				System.Threading.Thread.Sleep(1000);
			}

			GC.Collect();
			currentProcess.Refresh();
			postSessionCreationWorkingSet = (currentProcess.WorkingSet64 / 1024.0 / 1000.0);

			var counter = _TimeoutInSeconds + 60;

			TestContext.WriteLine("Waiting {0} seconds for session expiration...", counter);

			while (counter > 0)
			{
				System.Threading.Thread.Sleep(1000);
				counter--;
			}

			TestContext.WriteLine("Checking Sessions in store and cache...");
			var sessionIds = sessions.ToArray();
			result = Parallel.ForEach<string>(sessionIds, sessionId =>
			{
				HttpRequest request = null;
				HttpResponse response = null;
				HttpContext context = GetContext(out request, out response);

				bool locked;
				TimeSpan lockAge;
				object lockId;
				System.Web.SessionState.SessionStateActions actions;
				var storeData = provider.GetItem(context, sessionId, out locked, out lockAge, out lockId, out actions);

				Assert.IsNull(storeData);

				// Now check the cache!
				ISessionStateData sessionStateData;
				bool existsInCache = CheckSessionExistsInCache(provider, sessionId, out sessionStateData);
				if (existsInCache || sessionStateData != null)
				{
					TestContext.WriteLine("Session {0} still exists in cache!", sessionId);
				}
				else
				{
					sessions.Remove(sessionId);
				}
			});

			while (!result.IsCompleted)
			{
				System.Threading.Thread.Sleep(1000);
			}

			GC.Collect();
			GC.WaitForPendingFinalizers();
			currentProcess.Refresh();
			postSessionExpirationWorkingSet = (currentProcess.WorkingSet64 / 1024.0 / 1000.0);

			TestContext.WriteLine("Memory Usage: Initial = {0}MB, PostSessionCreation = {1}MB, PostSessionExpiration = {2}MB", initialWorkingSet, postSessionCreationWorkingSet, postSessionExpirationWorkingSet);
			TestContext.WriteLine("After expiration, session count = {0}", sessions.Count);

			currentProcess.Dispose();

			double memoryDifference = postSessionExpirationWorkingSet - initialWorkingSet;
			TestContext.WriteLine("Memory Difference -> {0}MB", memoryDifference);

			bool isMemoryExhausted = (memoryDifference > 20); // This should be based on the buffer size and number of sessions
			if (sessions.Count != 0)
			{
				Assert.Fail("{0} Sessions still exist in memory.  The memory has grown from {1}MB to {2}MB", sessions.Count, initialWorkingSet, postSessionExpirationWorkingSet);
			}
			if (isMemoryExhausted)
			{
				Assert.Fail("Excessive Memory Consumption.  Memory has grown by {0}MB", memoryDifference);
			}
		}
All Usage Examples Of MongoDB.Web.Providers.MongoDBSessionStateProvider::SetAndReleaseItemExclusive