public override void ResetItemTimeout(HttpContext context, string id)
        {
            MongoClient conn = GetConnection();
            IMongoCollection <BsonDocument> sessionCollection = GetSessionCollection(conn);

            var filter = Builders <BsonDocument> .Filter.Eq("_id", MongoSessionStateStoreHelpers.GetDocumentSessionId(id, ApplicationName));

            var update = Builders <BsonDocument> .Update.Set("Expires", DateTime.Now.AddMinutes(_config.Timeout.TotalMinutes).ToUniversalTime());

            this.UpdateSessionCollection(sessionCollection, filter, update);
        }
        public override void RemoveItem(HttpContext context, string id, object lockId, SessionStateStoreData item)
        {
            MongoClient conn = GetConnection();
            IMongoCollection <BsonDocument> sessionCollection = GetSessionCollection(conn);

            var filter = Builders <BsonDocument> .Filter.And(
                Builders <BsonDocument> .Filter.Eq("_id", MongoSessionStateStoreHelpers.GetDocumentSessionId(id, ApplicationName)),
                Builders <BsonDocument> .Filter.Eq("LockId", (Int32)lockId));

            this.DeleteSessionDocument(sessionCollection, filter);
        }
        public override void ReleaseItemExclusive(HttpContext context, string id, object lockId)
        {
            MongoClient conn = GetConnection();
            IMongoCollection <BsonDocument> sessionCollection = GetSessionCollection(conn);

            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("Locked", false)
                         .Set("Expires", DateTime.Now.AddMinutes(_config.Timeout.TotalMinutes).ToUniversalTime());

            this.UpdateSessionCollection(sessionCollection, filter, update);
        }
        /// <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>
        /// GetSessionStoreItem is called by both the GetItem and
        /// GetItemExclusive methods. GetSessionStoreItem retrieves the
        /// session data from the data source. If the lockRecord parameter
        /// is true (in the case of GetItemExclusive), then GetSessionStoreItem
        /// locks the record and sets a new LockId and LockDate.
        /// </summary>
        private SessionStateStoreData GetSessionStoreItem(
            bool lockRecord,
            HttpContext context,
            string id,
            out bool locked,
            out TimeSpan lockAge,
            out object lockId,
            out SessionStateActions actionFlags)
        {
            // Initial values for return value and out parameters.
            SessionStateStoreData item = null;

            lockAge     = TimeSpan.Zero;
            lockId      = null;
            locked      = false;
            actionFlags = 0;

            MongoClient conn = GetConnection();
            var         sessionCollection = GetSessionCollection(conn);

            // DateTime to check if current session item is expired.
            // String to hold serialized SessionStateItemCollection.
            BsonArray serializedItems = new BsonArray();
            // True if a record is found in the database.
            bool foundRecord = false;
            // True if the returned session item is expired and needs to be deleted.
            bool deleteData = false;
            // Timeout value from the data store.
            int timeout = 0;


            // lockRecord is true when called from GetItemExclusive and
            // false when called from GetItem.
            // Obtain a lock if possible. Ignore the record if it is expired.
            FilterDefinition <BsonDocument> query;

            if (lockRecord)
            {
                query = Builders <BsonDocument> .Filter.And(
                    Builders <BsonDocument> .Filter.Eq("_id", MongoSessionStateStoreHelpers.GetDocumentSessionId(id, ApplicationName)),
                    Builders <BsonDocument> .Filter.Eq("Locked", false),
                    Builders <BsonDocument> .Filter.Gt("Expires", DateTime.Now.ToUniversalTime()));

                var update = Builders <BsonDocument> .Update.Set("Locked", true)
                             .Set("LockDate", DateTime.Now.ToUniversalTime());

                var result = this.UpdateSessionCollection(sessionCollection, query, update);

                if (result.IsAcknowledged)
                {
                    locked = result.ModifiedCount == 0; // DocumentsAffected == 0 == No record was updated because the record was locked or not found.
                }
            }

            // Retrieve the current session item information.
            query = Builders <BsonDocument> .Filter.Eq("_id", MongoSessionStateStoreHelpers.GetDocumentSessionId(id, ApplicationName));

            var results = this.FindOneSessionItem(sessionCollection, query);

            if (results != null)
            {
                DateTime expires = results["Expires"].ToUniversalTime();

                if (expires < DateTime.Now.ToUniversalTime())
                {
                    // The record was expired. Mark it as not locked.
                    locked = false;
                    // The session was expired. Mark the data for deletion.
                    deleteData = true;
                }
                else
                {
                    foundRecord = true;
                }

                serializedItems = results["SessionItemJSON"].AsBsonArray;
                lockId          = results["LockId"].AsInt32;
                lockAge         = DateTime.Now.ToUniversalTime().Subtract(results["LockDate"].ToUniversalTime());
                actionFlags     = (SessionStateActions)results["Flags"].AsInt32;
                timeout         = results["Timeout"].AsInt32;
            }

            // If the returned session item is expired,
            // delete the record from the data source.
            if (deleteData)
            {
                query = Builders <BsonDocument> .Filter.Eq("_id", MongoSessionStateStoreHelpers.GetDocumentSessionId(id, ApplicationName));

                this.DeleteSessionDocument(sessionCollection, query);
            }

            // The record was not found. Ensure that locked is false.
            if (!foundRecord)
            {
                locked = false;
            }

            // If the record was found and you obtained a lock, then set
            // the lockId, clear the actionFlags,
            // and create the SessionStateStoreItem to return.
            if (foundRecord && !locked)
            {
                lockId = (int)lockId + 1;

                query = Builders <BsonDocument> .Filter.Eq("_id", MongoSessionStateStoreHelpers.GetDocumentSessionId(id, ApplicationName));

                var update = Builders <BsonDocument> .Update.Set("LockId", (int)lockId).Set("Flags", 0);

                this.UpdateSessionCollection(sessionCollection, query, update);

                // If the actionFlags parameter is not InitializeItem,
                // deserialize the stored SessionStateItemCollection.
                item = actionFlags == SessionStateActions.InitializeItem
                    ? CreateNewStoreData(context, (int)_config.Timeout.TotalMinutes)
                    : MongoSessionStateStoreHelpers.Deserialize(context, serializedItems, timeout);
            }

            return(item);
        }