Internal class for handling the storage of the session items in Couchbase
コード例 #1
0
        private static SessionStateItem LoadItem(MemoryStream ms)
        {
            var graph = new ObjectStateFormatter().Deserialize(ms) as Pair;

            if (graph == null)
            {
                return(null);
            }

            if (((byte)graph.First) != 1)
            {
                return(null);
            }

            var t      = (Triplet)graph.Second;
            var retval = new SessionStateItem
            {
                Flag    = (SessionStateActions)((byte)t.First),
                Timeout = (int)t.Second
            };

            var lockInfo = (Pair)t.Third;

            retval.LockId   = (ulong)lockInfo.First;
            retval.LockTime = DateTime.FromBinary((long)lockInfo.Second);

            return(retval);
        }
コード例 #2
0
        /// <summary>
        /// Releases a lock on an item in the session data store
        /// </summary>
        /// <param name="context">HttpContext for the current request</param>
        /// <param name="id">Session ID for the session</param>
        /// <param name="lockId">The lock identifier for the current request</param>
        public override void ReleaseItemExclusive(
            HttpContext context,
            string id,
            object lockId)
        {
            ResponseStatus   status;
            var              retries = 0;
            var              tmp     = (ulong)lockId;
            SessionStateItem e;

            do
            {
                // Load the header for the item with CAS
                e = SessionStateItem.Load(_bucket, id, true);

                // Bail if the entry does not exist, or the lock ID does not match our lock ID
                if (e == null || e.LockId != tmp)
                {
                    break;
                }

                // Attempt to clear the lock for this item and loop around until we succeed
                e.LockId   = 0;
                e.LockTime = DateTime.MinValue;
            } while (!e.SaveHeader(_bucket, id, _exclusiveAccess, out status) && retries++ < _maxRetryCount && status != ResponseStatus.KeyNotFound);
        }
コード例 #3
0
        private static SessionStateItem Get(IMemcachedClient client, bool acquireLock, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions)
        {
            locked  = false;
            lockId  = null;
            lockAge = TimeSpan.Zero;
            actions = SessionStateActions.None;

            var e = SessionStateItem.Load(client, id, false, _compressor, _isLoggingEnabled ? _logger : null);

            if (e == null)
            {
                return(null);
            }

            if (acquireLock)
            {
                // repeat until we can update the retrieved
                // item (i.e. nobody changes it between the
                // time we get it from the store and updates it s attributes)
                // Save() will return false if Cas() fails
                while (true)
                {
                    if (e.LockId > 0)
                    {
                        break;
                    }

                    actions = e.Flag;

                    e.LockId   = _exclusiveAccess ? e.HeadCas : 0;
                    e.LockTime = DateTime.UtcNow;
                    e.Flag     = SessionStateActions.None;

                    // try to update the item in the store
                    if (e.Save(client, id, true, _exclusiveAccess, _compressor, _isLoggingEnabled ? _logger : null))
                    {
                        locked = true;
                        lockId = e.LockId;

                        return(e);
                    }

                    // it has been modified between we loaded and tried to save it
                    e = SessionStateItem.Load(client, id, false, _compressor, _isLoggingEnabled ? _logger : null);
                    if (e == null)
                    {
                        return(null);
                    }
                }
            }

            locked  = true;
            lockAge = DateTime.UtcNow - e.LockTime;
            lockId  = e.LockId;
            actions = SessionStateActions.None;

            return(acquireLock ? null : e);
        }
コード例 #4
0
        public override void RemoveItem(HttpContext context, string id, object lockId, SessionStateStoreData item)
        {
            var tmp = (ulong)lockId;
            var e   = SessionStateItem.Load(client, id, true);

            if (e != null && e.LockId == tmp)
            {
                SessionStateItem.Remove(client, id);
            }
        }
コード例 #5
0
        public override void RemoveItem(HttpContext context, string id, object lockId, SessionStateStoreData item)
        {
            var tmp = (ulong)lockId;
            var e   = SessionStateItem.Load(_client, id, true, _compressor, _isLoggingEnabled ? _logger : null);

            if (e != null && e.LockId == tmp)
            {
                SessionStateItem.Remove(_client, id);
            }
        }
        public override void CreateUninitializedItem(HttpContext context, string id, int timeout)
        {
            var e = new SessionStateItem {
                Data = new SessionStateItemCollection(),
                Flag = SessionStateActions.InitializeItem,
                LockId = 0,
                Timeout = timeout
            };

            e.Save(client, id, false, false);
        }
コード例 #7
0
        public override void CreateUninitializedItem(HttpContext context, string id, int timeout)
        {
            var e = new SessionStateItem {
                Data = new SessionStateItemCollection(),
                Flag = SessionStateActions.InitializeItem,
                LockId = 0,
                Timeout = timeout
            };

            e.Save(_client, id, false, false, _compressor, _isLoggingEnabled ? _logger : null);
        }
コード例 #8
0
        public override void CreateUninitializedItem(HttpContext context, string id, int timeout)
        {
            var e = new SessionStateItem {
                Data    = new SessionStateItemCollection(),
                Flag    = SessionStateActions.InitializeItem,
                LockId  = 0,
                Timeout = timeout
            };

            e.Save(client, id, false, false);
        }
コード例 #9
0
        public override void CreateUninitializedItem(HttpContext context, string id, int timeout)
        {
            var e = new SessionStateItem {
                Data    = new SessionStateItemCollection(),
                Flag    = SessionStateActions.InitializeItem,
                LockId  = 0,
                Timeout = timeout
            };

            e.Save(_client, id, false, false, _compressor, _isLoggingEnabled ? _logger : null);
        }
コード例 #10
0
        /// <summary>
        /// Creates an uninitialized item in the database. This is only used for cookieless sessions
        /// regenerateExpiredSessionId attribute is set to true, which causes SessionStateModule to
        /// generate a new SessionID value when an expired session ID is encountered.
        /// </summary>
        /// <param name="context">HttpContext for the current request</param>
        /// <param name="id">Session ID for the new session</param>
        /// <param name="timeout">Timeout value for the session</param>
        public override void CreateUninitializedItem(HttpContext context, string id, int timeout)
        {
            var e = new SessionStateItem
            {
                Data    = new SessionStateItemCollection(),
                Flag    = SessionStateActions.InitializeItem,
                LockId  = 0,
                Timeout = timeout
            };

            bool keyNotFound;

            e.SaveAll(_bucket, id, false, out keyNotFound);
        }
コード例 #11
0
		private SessionStateItem Get(HttpContext context, bool acquireLock, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions)
		{
			locked = false;
			lockId = null;
			lockAge = TimeSpan.Zero;
			actions = SessionStateActions.None;

			var e = SessionStateItem.Load(this.client, id, false);
			if (e == null) return null;

			if (acquireLock)
			{
				// repeat until we can update the retrieved 
				// item (i.e. nobody changes it between the 
				// time we get it from the store and updates its attributes)
				// Save() will return false if Cas() fails
				while (true)
				{
					if (e.LockId > 0) break;

					actions = e.Flag;

					e.LockId = e.HeadCas;
					e.LockTime = DateTime.UtcNow;
					e.Flag = SessionStateActions.None;

					// try to update the item in the store
					if (e.Save(this.client, id, true, true))
					{
						locked = true;
						lockId = e.LockId;

						return e;
					}

					// it has been modifed between we loaded and tried to save it
					e = SessionStateItem.Load(this.client, id, false);
					if (e == null) return null;
				}
			}

			locked = true;
			lockAge = DateTime.UtcNow - e.LockTime;
			lockId = e.LockId;
			actions = SessionStateActions.None;

			return acquireLock ? null : e;
		}
コード例 #12
0
        public override void ResetItemTimeout(HttpContext context, string id)
        {
            SessionStateItem e;

            do
            {
                // Load the item with CAS
                e = SessionStateItem.Load(_client, id, false, _compressor, _isLoggingEnabled ? _logger : null);
                if (e == null)
                {
                    break;
                }

                // Try to save with CAS, and loop around until we succeed
            } while (!e.Save(_client, id, false, _exclusiveAccess, _compressor, _isLoggingEnabled ? _logger : null));
        }
コード例 #13
0
		public override void ReleaseItemExclusive(HttpContext context, string id, object lockId)
		{
			if (!(lockId is ulong))
				return;

			var tmp = (ulong)lockId;
			var e = SessionStateItem.Load(this.client, id, true);

			if (e != null && e.LockId == tmp)
			{
				e.LockId = 0;
				e.LockTime = DateTime.MinValue;

				e.Save(this.client, id, true, true);
			}
		}
コード例 #14
0
        public override void ResetItemTimeout(HttpContext context, string id)
        {
            SessionStateItem e;

            do
            {
                // Load the item with CAS
                e = SessionStateItem.Load(client, id, false);
                if (e == null)
                {
                    break;
                }

                // Try to save with CAS, and loop around until we succeed
            } while (!e.Save(client, id, false, exclusiveAccess));
        }
コード例 #15
0
        /// <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)
        {
            bool             keyNotFound;
            var              retries = 0;
            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, out keyNotFound) && retries++ < _maxRetryCount && !keyNotFound);
        }
コード例 #16
0
            public static SessionStateItem Load(string headerPrefix, string dataPrefix, IMemcachedClient client, string id, bool metaOnly)
            {
                // Load the header for the item
                var header = client.GetWithCas <byte[]>(headerPrefix + id);

                if (header.Result == null)
                {
                    return(null);
                }

                // Deserialize the header values
                SessionStateItem entry;

                using (var ms = new MemoryStream(header.Result)) {
                    entry = SessionStateItem.LoadItem(ms);
                }
                entry.HeadCas = header.Cas;

                // Bail early if we are only loading the meta data
                if (metaOnly)
                {
                    return(entry);
                }

                // Load the data for the item
                var data = client.GetWithCas <byte[]>(dataPrefix + id);

                if (data.Result == null)
                {
                    return(null);
                }
                entry.DataCas = data.Cas;

                // Deserialize the data
                using (var ms = new MemoryStream(data.Result)) {
                    using (var br = new BinaryReader(ms)) {
                        entry.Data = SessionStateItemCollection.Deserialize(br);
                    }
                }

                // Return the session entry
                return(entry);
            }
コード例 #17
0
        /// <summary>
        /// Updates the expiration date and time of an item in the session data store
        /// </summary>
        /// <param name="context">HttpContext for the current request</param>
        /// <param name="id">Session ID for the session</param>
        public override void ResetItemTimeout(
            HttpContext context,
            string id)
        {
            bool             keyNotFound;
            var              retries = 0;
            SessionStateItem e;

            do
            {
                // Load the item with CAS
                e = SessionStateItem.Load(_bucket, id, false);
                if (e == null)
                {
                    break;
                }

                // Try to save with CAS, and loop around until we succeed
            } while (!e.SaveAll(_bucket, id, _exclusiveAccess, out keyNotFound) && retries++ < _maxRetryCount && !keyNotFound);
        }
コード例 #18
0
        public override void ReleaseItemExclusive(HttpContext context, string id, object lockId)
        {
            var tmp = (ulong)lockId;
            SessionStateItem e;

            do
            {
                // Load the header for the item with CAS
                e = SessionStateItem.Load(_client, id, true, _compressor, _isLoggingEnabled ? _logger : null);

                // Bail if the entry does not exist, or the lock ID does not match our lock ID
                if (e == null || e.LockId != tmp)
                {
                    break;
                }

                // Attempt to clear the lock for this item and loop around until we succeed
                e.LockId   = 0;
                e.LockTime = DateTime.MinValue;
            } while (!e.Save(_client, id, true, _exclusiveAccess, _compressor, _isLoggingEnabled ? _logger : null));
        }
コード例 #19
0
		public override void SetAndReleaseItemExclusive(HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem)
		{
			SessionStateItem e = null;
			bool existing = false;

			if (!newItem)
			{
				if (!(lockId is ulong))
					return;

				var tmp = (ulong)lockId;
				e = SessionStateItem.Load(this.client, id, true);
				existing = e != null;

				// if we're expecting an existing item, but
				// it's not in the cache
				// or it's not locked
				// or it's locked by someone else, then quit
				if (!newItem
					&& (!existing
						|| e.LockId == 0
						|| e.LockId != tmp))
					return;
			}

			if (!existing) 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;

			e.Save(this.client, id, false, existing && !newItem);
		}
コード例 #20
0
			public static SessionStateItem Load(IMemcachedClient client, string id, bool metaOnly)
			{
				var header = client.GetWithCas<byte[]>(HeaderPrefix + id);
				if (header.Result == null) return null;

				SessionStateItem entry;

				using (var ms = new MemoryStream(header.Result))
					entry = SessionStateItem.LoadItem(ms);

				if (entry != null) entry.HeadCas = header.Cas;
				if (metaOnly) return entry;

				var data = client.GetWithCas<byte[]>(DataPrefix + id);
				if (data.Result == null) return null;

				using (var ms = new MemoryStream(data.Result))
				using (var br = new BinaryReader(ms))
					entry.Data = SessionStateItemCollection.Deserialize(br);

				entry.DataCas = data.Cas;

				return entry;
			}
コード例 #21
0
            /// <summary>
            /// Loads a sessions store header data from the passed in stream
            /// </summary>
            /// <param name="s">Stream to load the item from</param>
            /// <returns>Value read from the stream, null on failure</returns>
            private static SessionStateItem LoadHeader(
                Stream s)
            {
                var graph = new ObjectStateFormatter().Deserialize(s) as Pair;
                if (graph == null)
                    return null;

                if (((byte)graph.First) != 1)
                    return null;

                var t = (Triplet)graph.Second;
                var retval = new SessionStateItem {
                    Flag = (SessionStateActions)((byte)t.First),
                    Timeout = (int)t.Second
                };

                var lockInfo = (Pair)t.Third;

                retval.LockId = (ulong)lockInfo.First;
                retval.LockTime = DateTime.FromBinary((long)lockInfo.Second);

                return retval;
            }
コード例 #22
0
        /// <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.Save(_bucket, id, false, _exclusiveAccess && !newItem));
        }
コード例 #23
0
		public override void ResetItemTimeout(HttpContext context, string id)
		{
			var e = SessionStateItem.Load(this.client, id, false);
			if (e != null)
				e.Save(this.client, id, false, true);
		}
コード例 #24
0
        public override void SetAndReleaseItemExclusive(HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem)
        {
            SessionStateItem e = null;
            bool existing = false;

            if (!newItem)
            {
                if (!(lockId is ulong))
                    return;

                var tmp = (ulong)lockId;
                e = SessionStateItem.Load(this.client, id, true);
                existing = e != null;

                // if we're expecting an existing item, but
                // it's not in the cache
                // or it's not locked
                // or it's locked by someone else, then quit
                if (!newItem
                    && (!existing
                        || e.LockId == 0
                        || e.LockId != tmp))
                    return;
            }

            if (!existing) 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;

            e.Save(this.client, id, false, existing && !newItem);
        }
コード例 #25
0
        /// <summary>
        /// Retrieves the session data from the data source. If the lockRecord parameter is true
        /// (in the case of GetItemExclusive), then the record is locked and we return a new lockId
        /// and lockAge.
        /// </summary>
        /// <param name="bucket">Reference to the couchbase bucket we are using</param>
        /// <param name="context">HttpContext for the current request</param>
        /// <param name="acquireLock">True to aquire the lock, false to not aquire it</param>
        /// <param name="id">Session ID for the session</param>
        /// <param name="locked">Returns true if the session item is locked, otherwise false</param>
        /// <param name="lockAge">Returns the amount of time that the item has been locked</param>
        /// <param name="lockId">Returns lock identifier for the current request</param>
        /// <param name="actions">Indicates whether the current sessions is an uninitialized, cookieless session</param>
        /// <returns>SessionStateItem object containing the session state data</returns>
        public static SessionStateItem GetSessionStoreItem(
            IBucket bucket,
            HttpContext context,
            bool acquireLock,
            string id,
            out bool locked,
            out TimeSpan lockAge,
            out object lockId,
            out SessionStateActions actions)
        {
            locked  = false;
            lockId  = null;
            lockAge = TimeSpan.Zero;
            actions = SessionStateActions.None;

            var e = SessionStateItem.Load(bucket, id, false);

            if (e == null)
            {
                return(null);
            }

            if (acquireLock)
            {
                // repeat until we can update the retrieved
                // item (i.e. nobody changes it between the
                // time we get it from the store and updates it s attributes)
                // Save() will return false if Cas() fails
                while (true)
                {
                    if (e.LockId > 0)
                    {
                        break;
                    }

                    actions = e.Flag;

                    e.LockId   = _exclusiveAccess ? e.HeadCas : 0;
                    e.LockTime = DateTime.UtcNow;
                    e.Flag     = SessionStateActions.None;

                    ResponseStatus status;
                    // try to update the item in the store
                    if (e.SaveHeader(bucket, id, _exclusiveAccess, out status))
                    {
                        locked = true;
                        lockId = e.LockId;

                        return(e);
                    }
                    if (status == ResponseStatus.KeyNotFound)
                    {
                        break;
                    }

                    // it has been modified between we loaded and tried to save it
                    e = SessionStateItem.Load(bucket, id, false);
                    if (e == null)
                    {
                        return(null);
                    }
                }
            }

            locked  = true;
            lockAge = DateTime.UtcNow - e.LockTime;
            lockId  = e.LockId;
            actions = SessionStateActions.None;

            return(acquireLock ? null : e);
        }
コード例 #26
0
        /// <summary>
        /// Creates an uninitialized item in the database. This is only used for cookieless sessions
        /// regenerateExpiredSessionId attribute is set to true, which causes SessionStateModule to 
        /// generate a new SessionID value when an expired session ID is encountered.
        /// </summary>
        /// <param name="context">HttpContext for the current request</param>
        /// <param name="id">Session ID for the new session</param>
        /// <param name="timeout">Timeout value for the session</param>
        public override void CreateUninitializedItem(HttpContext context, string id, int timeout)
        {
            var e = new SessionStateItem
            {
                Data = new SessionStateItemCollection(),
                Flag = SessionStateActions.InitializeItem,
                LockId = 0,
                Timeout = timeout
            };

            bool keyNotFound;
            e.SaveAll(_bucket, id, false, out keyNotFound);
        }