Пример #1
0
        //The item is expired, call the "Refresh" action of this item to get a refresh value
        //1. If there's not enough worker threads, the dispatching thread will wait until the below 2 conditions happend:
        //(1). There is worker threads available
        //(2). There is user event comming (Add/Remove etc.)
        //2. If there's at least one worker thread, the dispatching thread will schedule the "Refresh" action in one worker thread
        //after the worker thread end to refresh the cache item, it will release the worker thread resource, and notify the
        //dispatching thread, so that other expired cache items wait for refresh worker thread can do their refresh job
        private bool RefreshExpiredCache(SchedulerKey sk, CacheItem ci)
        {
            //Refresh the expired item now, but firstly we should get a token
            if (Interlocked.Decrement(ref m_availRefreshThreadCount) < 0)
            {
                //Got an invalid token, return it
                Interlocked.Increment(ref m_availRefreshThreadCount);

                //No available refresh thread now, wait for one
                LogManager.Info("CacheManager:ProcessTimerEvents", string.Format("Begin to wait for refreshing thread token with key [{0}]", sk.Key));

                m_waitHandle.WaitOne();

                //Either there's an user event comming or a refresh thread token is available
                LogManager.Info("CacheManager:ProcessTimerEvents", string.Format("End to wait for refreshing thread token with key [{0}]", sk.Key));

                //No need to wait again, start a new loop
                return false;
            }

            //Save the last expiration time
            ci.LastExpirationInfo.LastExpiration = ci.NextExpirationTime;
            //Update the next expiration time for next schedule
            ci.NextExpirationTime = ci.Expiration.NextExpiration(ci.LastExpirationInfo);

            //Validation
            TimeSpan ts = ci.NextExpirationTime - ci.LastExpirationInfo.LastExpiration;
            if (ts.TotalMilliseconds < MIN_WAIT_TIME)
            {
                LogManager.Warn("CacheManager:ProcessTimerEvents", "Too short time interval, ts=" + ts.TotalMilliseconds);

                //wait 3s
                ci.NextExpirationTime = ci.LastExpirationInfo.LastExpiration.AddMilliseconds(3000);
            }

            //Re-schedule again
            m_heap.Remove(sk);
            m_heap.Add(new SchedulerKey(ci.NextExpirationTime, sk.Key), DUMMY);

            //Fire the refresh action
            Task.Factory.StartNew(() =>
            {
                try
                {
                    ci.RefreshAsync();

                    //Release the token
                    Interlocked.Increment(ref m_availRefreshThreadCount);

                    //And notify the listeners
                    m_waitHandle.Set();
                }
                catch (Exception ex)
                {
                    LogManager.Error(string.Format("Task for key [{0}] exception", ci.Key), ex);
                }
            });

            return true;
        }
Пример #2
0
        private bool DoGetOrAdd(OperationEvent operEvent)
        {
            CacheItem ci = operEvent.OperObject as CacheItem;
            if (ci == null)
            {
                LogManager.Warn("CacheManager:Assert Failure", "DoGetOrAdd a null item");
                return true;
            }

            //Cache Item
            bool added = m_cacheItems.TryAdd(ci.Key, ci);
            if (added)
            {
                //Add the SchedulerKey at the same time
                SchedulerKey sk = new SchedulerKey(ci.NextExpirationTime, ci.Key);
                if (m_heap.ContainsKey(sk))
                {
                    //This should not happen. If it does, then this is a critial bug!
                    LogManager.Warn("CacheManager:Assert Failure", string.Format("The SchedulerKey key[{0}] is already exising", sk.ToString()));
                }
                else
                {
                    m_heap.Add(sk, DUMMY);
                }

                operEvent.OperResult = ci;

                LogManager.Info("CacheManager:DoGetOrAdd", string.Format("The key [{0}] is added, value=[{1}]", ci.Key, ci.ToString()));
            }
            else
            {
                CacheItem existingItem = null;
                if (!m_cacheItems.TryGetValue(ci.Key, out existingItem))
                {
                    //This should not happen. If it does, then this is a critial bug!
                    LogManager.Warn("CacheManager:Assert Failure", string.Format("The expected existing key[{0}] doesn't exist", ci.Key));
                }
                else if (existingItem == null)
                {
                    //This should not happen. If it does, then this is a critial bug!
                    LogManager.Warn("CacheManager:Assert Failure", string.Format("The expected existing key[{0}] is null", ci.Key));
                }
                else
                {
                    operEvent.OperResult = existingItem;
                    //LogManager.Debug("CacheManager:DoGetOrAdd", string.Format("The key [{0}] is already existing, value=[{1}]",
                    //    ci.Key, existingItem.ToString()));
                }
            }

            return true;
        }
Пример #3
0
        private bool DoRemove(CacheItem ci)
        {
            if (ci == null)
            {
                LogManager.Warn("CacheManager:Assert Failure", "DoRemove a null item");
                return true;
            }

            CacheItem value = null;
            if (!m_cacheItems.TryRemove(ci.Key, out value))
            {
                LogManager.Warn("CacheManager:DoRemove", string.Format("The CacheItem key[{0}] is already removed", ci.Key));
            }

            SchedulerKey sk = new SchedulerKey(ci.NextExpirationTime, ci.Key);
            if (!m_heap.ContainsKey(sk))
            {
                LogManager.Warn("CacheManager:DoRemove", string.Format("The SchedulerKey key[{0}] is already removed", sk.ToString()));
            }
            else
            {
                m_heap.Remove(sk);
            }

            LogManager.Info("CacheManager:DoRemove", string.Format("The key [{0}] is removed", ci.Key));
            return true;
        }
Пример #4
0
        private bool DoAdd(CacheItem ci)
        {
            if (ci == null)
            {
                LogManager.Warn("CacheManager:Assert Failure", "DoAdd a null item");
                return true;
            }

            //Cache Item
            bool added = m_cacheItems.TryAdd(ci.Key, ci);
            if (added)
            {
                //Add the SchedulerKey at the same time
                SchedulerKey sk = new SchedulerKey(ci.NextExpirationTime, ci.Key);
                if (m_heap.ContainsKey(sk))
                {
                    //This should not happen. If it does, then this is a critial bug!
                    LogManager.Warn("CacheManager:Assert Failure", string.Format("The SchedulerKey key[{0}] is already exising", sk.ToString()));
                }
                else
                {
                    m_heap.Add(sk, DUMMY);
                }
            }

            if (added)
            {
                LogManager.Info("CacheManager:DoAdd", string.Format("The key [{0}] is added, value=[{1}]", ci.Key, ci.ToString()));
            }
            else
            {
                LogManager.Info("CacheManager:DoAdd", string.Format("The key [{0}] is already existing", ci.Key));
            }

            return true;
        }