private async Task <bool> CreateUpdateItem(string region, object item)
        {
            var mongoCollection = MongoUtilities.InitializeMongoDatabase(region, _mongoConnectionString);

            Task.Factory.StartNew(() => RemoveExpired(region));
            var results = await Task.Factory.StartNew(() => mongoCollection.Save(item));

            return(await MongoUtilities.VerifyReturnMessage(results));
        }
        /// <summary>
        /// get the count of items in a cache region
        /// </summary>
        /// <param name="region"></param>
        /// <returns></returns>
        public override async Task <long> Count(string region)
        {
            if (!_isEnabled)
            {
                return(0);
            }
            var mongoCollection = MongoUtilities.InitializeMongoDatabase(region, _mongoConnectionString);

            return(await Task.Factory.StartNew(() => mongoCollection.Count()));
        }
        /// <summary>
        /// removes all items from a cache region
        /// </summary>
        /// <param name="region"></param>
        /// <returns></returns>
        public async override Task <bool> RemoveAll(string region)
        {
            if (!_isEnabled)
            {
                return(true);
            }

            var mongoDatabase = MongoUtilities.GetDatabaseFromUrl(new MongoUrl(_mongoConnectionString));
            await Task.Factory.StartNew(() => mongoDatabase.DropCollection(region));

            return(true);
        }
        /// <summary>
        /// removes all items from cache from all regions
        /// </summary>
        /// <returns></returns>
        public async override Task <bool> RemoveAll()
        {
            if (!_isEnabled)
            {
                return(true);
            }

            await
            Task.Factory.StartNew(
                () => MongoUtilities.GetDatabaseFromUrl(new MongoUrl(_mongoConnectionString)).Drop());

            return(true);
        }
        /// <summary>
        /// removes an item from cache region
        /// </summary>
        /// <param name="cacheKey"></param>
        /// <param name="region"></param>
        /// <returns></returns>
        public override async Task <bool> Remove(object cacheKey, string region)
        {
            if (!_isEnabled)
            {
                return(true);
            }

            var mongoCollection = MongoUtilities.InitializeMongoDatabase(region, _mongoConnectionString);

            var query   = Query.EQ("CacheKey", cacheKey.ToString());
            var results = await Task.Factory.StartNew(() => mongoCollection.Remove(query));

            return(await MongoUtilities.VerifyReturnMessage(results));
        }
        /// <summary>
        ///     Initialize from config
        /// </summary>
        /// <param name="name"></param>
        /// <param name="config">Config properties</param>
        public override void Initialize(string name, NameValueCollection config)
        {
            base.Initialize(name, config);

            var timeout = config["timeout"];

            if (string.IsNullOrEmpty(timeout))
            {
                timeout = "20";
            }

            _cacheExpirationTime = 60;

            if (!int.TryParse(timeout, out _cacheExpirationTime))
            {
                throw new ConfigurationErrorsException("invalid timeout value");
            }

            var host = config["host"];

            if (string.IsNullOrEmpty(host))
            {
                throw new ConfigurationErrorsException("host must be set to the appropriate value");
            }

            // port is optional, if not provided it will use the base mongo port number
            var port = config["port"];

            var baseDbName = config["env"];

            if (string.IsNullOrEmpty(baseDbName))
            {
                throw new ConfigurationErrorsException("env must be set to the appropriate value");
            }

            _isEnabled = true;
            var enabled = config["enable"];

            if (enabled == null)
            {
                _isEnabled = true;
            }
            else
            {
                bool.TryParse(config["enable"], out _isEnabled);
            }

            _mongoConnectionString = host.ToLower().StartsWith("mongodb://") ?
                                     host : MongoUtilities.GetMongoDatabaseString(host, port, baseDbName);
        }
        private async Task <dynamic> GetItem(object cacheKey, string region)
        {
            var item = await Task.Factory.StartNew(() => MongoUtilities.InitializeMongoDatabase(region, _mongoConnectionString).AsQueryable <dynamic>()
                                                   .AsParallel()
                                                   .FirstOrDefault(x => x.CacheKey.Equals(cacheKey.ToString(), StringComparison.CurrentCultureIgnoreCase) && x.Expires > DateTime.UtcNow));

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

            // todo can be removed after dec
            if (GlobalUtilities.DoesPropertyExist(item, "AllowSliddingTime") || GlobalUtilities.DoesPropertyExist(item.CacheOptions.AllowSliddingTime, "AllowSliddingTime"))
            {
                await UpdateSliddingTime(region, item);
            }

            return(item);
        }
        /// <summary>
        /// remove expired items by region
        /// </summary>
        /// <param name="region"></param>
        /// <returns></returns>
        public async override Task <bool> RemoveExpired(string region)
        {
            if (!_isEnabled)
            {
                return(true);
            }

            var mongoCollection = MongoUtilities.InitializeMongoDatabase(region, _mongoConnectionString);

            var item = await Task.Factory.StartNew(() => mongoCollection.AsQueryable <CacheItem>().AsParallel().Where(x => x.Expires < DateTime.UtcNow).Select(x => x.Id));

            var query2 = Query.In("_id", new BsonArray(item));

            mongoCollection.Remove(query2);

            if (item.Any())
            {
                // todo add logging
            }

            return(true);
        }