public static TriggerAsynchronousFetchStatus TriggerAsynchronousFetch <T>(LoadSerializedObjectDelegate <T> loadObject, string cacheItemName
                                                                                  , string iterationKey, CacheItemContainer cacheItemContainer)
            where T : class
        {
            ContinuousCacheAccessThreadHelper <T> threadHelper;
            Thread thread;

            // we are in the extended lifespan, so we need to check whether we have to reload the object
            if (ContinuousCacheAccessSynchronizationManager.SetIsFetchingDataFlagToTrue(cacheItemContainer.CacheKey))
            {
                #region debug
#if DEBUG
                Trace.WriteLine(DebugConstants.DEBUG_PREFIX + "TRIGGER ASYNCHRONOUS FETCH: Initialize asynchronous fetch");
#endif
                #endregion

                threadHelper = ContinuousCacheAccessThreadHelper <T> .GetInstance(loadObject, cacheItemName, iterationKey);

                thread = new Thread(threadHelper.FetchAndInsertData);
                thread.Start();
                return(TriggerAsynchronousFetchStatus.SucessfullyInitialized);
            }
            else
            {
                #region debug
#if DEBUG
                Trace.WriteLine(DebugConstants.DEBUG_PREFIX + "TRIGGER ASYNCHRONOUS FETCH: Already in process...");
#endif
                #endregion

                return(TriggerAsynchronousFetchStatus.AlreadyFetching);
            }
        }
예제 #2
0
        /// <summary>
        /// Gets the instance.
        /// </summary>
        /// <param name="loadObject">The load object.</param>
        /// <param name="cacheItemName">Name of the cache item.</param>
        /// <param name="iterationKey">The iteration key.</param>
        /// <returns></returns>
        internal static ContinuousCacheAccessThreadHelper <T> GetInstance(LoadSerializedObjectDelegate <T> loadObject, string cacheItemName, string iterationKey)
        {
            ContinuousCacheAccessThreadHelper <T> record = new ContinuousCacheAccessThreadHelper <T>();

            record._LoadObjectDelegate = loadObject;
            record._CacheItemName      = cacheItemName;
            record._IterationKey       = iterationKey ?? string.Empty;

            return(record);
        }
예제 #3
0
        /// <summary>
        /// Loads from cache.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="cacheItemName">Name of the cache item.</param>
        /// <param name="iterationKey">The iteration key.</param>
        /// <param name="loadObject">The load object.</param>
        /// <returns></returns>
        public static T LoadFromCache <T>(string cacheItemName, string iterationKey, LoadSerializedObjectDelegate <T> loadObject) where T : class
        {
            T returnObject = default(T);

            // get the section
            CacheItemContainer cacheItemContainer = CreateSaveItemInstance(cacheItemName);
            string             cacheKey           = cacheItemContainer.CacheKey + iterationKey ?? string.Empty;

            if (_StaticCacheController.Enabled && cacheItemContainer.CacheItem.Enabled)
            {// use cache
                #region InProcess
                returnObject = _Cache[cacheKey] as T;
                if (returnObject == null)
                {
                    lock (ContinuousCacheAccessSynchronizationManager.CacheItemNameLocks[cacheItemName])
                    {
                        // check again in case the object was inserted into cache after the conditional statement but before the Monitor lock
                        returnObject = _Cache[cacheKey] as T;

                        if (returnObject == null)
                        {// get new object and cache it
                            #region debug
#if DEBUG
                            Trace.WriteLine(DebugConstants.DEBUG_PREFIX + "Item not found at cache");
#endif
                            #endregion

                            try { returnObject = loadObject.Invoke(); }
                            catch (Exception e) { throw new CachingException("An error occurred during the execution of the loadObject delegate. See the inner exception for further details.", e); }

                            if (returnObject != null)
                            {
                                cacheItemContainer.LatestFetch = DateTime.UtcNow;

                                CacheItemPolicy cacheItemPolicy = new CacheItemPolicy();
                                cacheItemPolicy.Priority           = cacheItemContainer.CacheItem.CacheItemPriority;
                                cacheItemPolicy.AbsoluteExpiration = cacheItemContainer.ActualExpiryDate;

                                SlimCacheManager._Cache.Set(
                                    cacheKey
                                    , returnObject
                                    , cacheItemPolicy);

                                #region debug
#if DEBUG
                                Trace.WriteLine("\n" + DebugConstants.DEBUG_PREFIX + "\n*INPROCESS CACHE INSERT:\n*\t\t\tInserted new object into cache at " + cacheItemContainer.LatestFetch.ToString("HH:mm:ss.fff")
                                                + "\n*\t\t\tActual expiry date: " + cacheItemContainer.ActualExpiryDate.ToString("HH:mm:ss.fff")
                                                + "\n*\t\t\tInserted new stale key with expiry date: " + cacheItemContainer.SpecifiedExpiryDate.ToString("HH:mm:ss.fff")
                                                + "\n*\t\t\tKey: " + cacheItemContainer.CacheKey
                                                + "\n************************************************************************************************\n");
#endif
                                #endregion
                            }

                            #region debug
#if DEBUG
                            Trace.WriteLine(DebugConstants.DEBUG_PREFIX + "Item inserted at normal cache call");
#endif
                            #endregion
                        }
                    }
                }
                else
                {
                    if (cacheItemContainer.CacheItem.UseContinuousAccess &&
                        cacheItemContainer.IsInExtendedLifeSpan(DateTime.UtcNow))
                    {
                        #region debug
#if DEBUG
                        Trace.WriteLine(DebugConstants.DEBUG_PREFIX + "IsInExtendedLifeSpan at " + DateTime.UtcNow.ToString("HH:mm:ss.fff"));
#endif
                        #endregion

                        // we are in the extended lifespan, so we need to check whether we have to reload the object
                        ContinuousCacheAccessSynchronizationManager.TriggerAsynchronousFetch <T>(loadObject, cacheItemName, iterationKey, cacheItemContainer);
                    }
                }
                #endregion
            }
            else
            {// don't use cache
                try { returnObject = loadObject.Invoke(); }
                catch (Exception e) { throw new CachingException("An error occurred during the execution of the loadObject delegate. See the inner exception for further details.", e); }
            }

            return(returnObject);
        }
예제 #4
0
 /// <summary>
 /// Loads from cache.
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="cacheItemName">Name of the cache item.</param>
 /// <param name="loadObject">The load object.</param>
 /// <returns></returns>
 public static T LoadFromCache <T>(string cacheItemName, LoadSerializedObjectDelegate <T> loadObject) where T : class
 {
     return(LoadFromCache <T>(cacheItemName, null, loadObject));
 }
        public static TriggerAsynchronousFetchStatus TriggerAsynchronousFetch <T>(LoadSerializedObjectDelegate <T> loadObject, string cacheItemName
                                                                                  , string iterationKey, CacheItemContainer cacheItemContainer)
            where T : class
        {
            ContinuousCacheAccessThreadHelper <T> threadHelper;
            Thread thread;

            switch (cacheItemContainer.CacheMode)
            {
            case CacheMode.InProcess:

                // we are in the extended lifespan, so we need to check whether we have to reload the object
                if (ContinuousCacheAccessSynchronizationManager.SetIsFetchingDataFlagToTrue(cacheItemContainer.CacheKey))
                {
                    #region debug
#if DEBUG
                    Trace.WriteLine(DebugConstants.DEBUG_PREFIX + "TRIGGER ASYNCHRONOUS FETCH: Initialize asynchronous fetch");
#endif
                    #endregion

                    threadHelper = ContinuousCacheAccessThreadHelper <T> .GetInstance(loadObject, cacheItemName, iterationKey);

                    thread = new Thread(threadHelper.FetchAndInsertData);
                    thread.Start();
                    return(TriggerAsynchronousFetchStatus.SucessfullyInitialized);
                }
                else
                {
                    #region debug
#if DEBUG
                    Trace.WriteLine(DebugConstants.DEBUG_PREFIX + "TRIGGER ASYNCHRONOUS FETCH: Already in process...");
#endif
                    #endregion

                    return(TriggerAsynchronousFetchStatus.AlreadyFetching);
                }


            case CacheMode.Memcached:
            case CacheMode.MemcachedProtocolBufferSerialization:

                DateTime temporaryExpiry = DateTime.UtcNow.Add(cacheItemContainer.CacheItem.LifeSpan);

                #region debug
#if DEBUG
                Trace.WriteLine(DebugConstants.DEBUG_PREFIX + "TRIGGER ASYNCHRONOUS FETCH MEMCACHED: Try to add stale key with temporary expiry date " + temporaryExpiry.ToString("HH:mm:ss.fff"));
#endif
                #endregion

                if (DistributedCache.Add(cacheItemContainer.MemcachedStaleCacheKey, new object(), temporaryExpiry))
                {    // great, we have to reload now
                    #region debug
#if DEBUG
                    Trace.WriteLine(DebugConstants.DEBUG_PREFIX + "TRIGGER ASYNCHRONOUS FETCH MEMCACHED: Initialize asynchronous fetch");
#endif
                    #endregion

                    threadHelper = ContinuousCacheAccessThreadHelper <T> .GetInstance(loadObject, cacheItemName, iterationKey);

                    thread = new Thread(threadHelper.FetchAndInsertMemcachedData);
                    thread.Start();

                    return(TriggerAsynchronousFetchStatus.SucessfullyInitialized);
                }
                else
                {
                    #region debug
#if DEBUG
                    Trace.WriteLine(DebugConstants.DEBUG_PREFIX + "TRIGGER ASYNCHRONOUS FETCH MEMCACHED: Already in process...");
#endif
                    #endregion

                    return(TriggerAsynchronousFetchStatus.AlreadyFetching);
                }

            default: throw new ArgumentException("CacheMode " + cacheItemContainer.CacheMode + " not allowed");
            }
        }
예제 #6
0
        /// <summary>
        /// Loads the object from cache.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="name">The name.</param>
        /// <param name="iterationKey">The iteration key.</param>
        /// <param name="loadObject">The load object.</param>
        /// <returns></returns>
        private static T LoadObjectFromCache <T>(string name, string iterationKey, LoadSerializedObjectDelegate <T> loadObject)
        {
            T returnObject = default(T);

            // get the section
            ICacheController section = CacheControllerSection;
            ICacheItem       item    = CreateSaveItemInstance(section, name, iterationKey);

            string cacheKey = GetCacheKey(item, iterationKey);

            if (section.Enabled && item.Enabled)
            {// use cache
                if (item.IsClustered)
                {
                    try
                    {
                        returnObject = (T)ClusteredCacheManager.GetCacheItem(
                            cacheKey
                            , delegate { return(loadObject()); }
                            , item.CacheItemPriority
                            , true);
                    }
                    catch (Exception e)
                    {
                        throw new CachingException("An error occurred during the retrieval of the business object from the cache collection. See the inner exception for further details.", e);
                    }
                }
                else
                {
                    lock (_CacheLock)
                    {
                        if (HttpRuntime.Cache[cacheKey] == null)
                        {// get new object and cache it
                            try
                            {
                                if (item.Minutes < 0 && item.Seconds < 0)
                                {
                                    throw new CachingException("You must specify either a seconds or minutes value for a non clusterd cache item.");
                                }

                                DateTime expire = item.Seconds < 0 ? DateTime.UtcNow.AddMinutes(item.Minutes) : DateTime.UtcNow.AddSeconds(item.Seconds);

                                returnObject = loadObject();
                                if (returnObject != null)
                                {
                                    HttpRuntime.Cache.Remove(cacheKey);
                                    HttpRuntime.Cache.Insert(cacheKey, returnObject, null, expire, System.Web.Caching.Cache.NoSlidingExpiration, item.CacheItemPriority, null);
                                }
                            }
                            catch (Exception e)
                            {
                                throw new CachingException("An error occurred during the execution of the loadObject delegate. See the inner exception for further details.", e);
                            }
                        }
                        else
                        {// get object from cache
                            try
                            {
                                returnObject = (T)HttpRuntime.Cache[cacheKey];
                            }
                            catch (Exception e)
                            {
                                throw new CachingException("An error occurred during the retrieval of the business object from the cache collection. See the inner exception for further details.", e);
                            }
                        }
                    }
                }
            }
            else
            {// don't use cache
                try
                {
                    returnObject = loadObject();
                }
                catch (Exception e)
                {
                    throw new CachingException("An error occurred during the execution of the loadObject delegate. See the inner exception for further details.", e);
                }
            }

            return(returnObject);
        }
예제 #7
0
 /// <summary>
 /// Loads from cache.
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="name">The name.</param>
 /// <param name="iterationKey">The iteration key.</param>
 /// <param name="loadObject">The load object.</param>
 /// <returns></returns>
 public static T LoadFromCache <T>(string name, string iterationKey, LoadSerializedObjectDelegate <T> loadObject)
 {
     return(LoadObjectFromCache <T>(name, iterationKey, loadObject));
 }
예제 #8
0
 /// <summary>
 /// Loads from cache.
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="name">The name.</param>
 /// <param name="loadObject">The load object.</param>
 /// <returns></returns>
 public static T LoadFromCache <T>(string name, LoadSerializedObjectDelegate <T> loadObject)
 {
     return(LoadObjectFromCache <T>(name, null, loadObject));
 }
예제 #9
0
        /// <summary>
        /// Loads from cache.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="cacheItemName">Name of the cache item.</param>
        /// <param name="iterationKey">The iteration key.</param>
        /// <param name="loadObject">The load object.</param>
        /// <returns></returns>
        public static T LoadFromCache <T>(string cacheItemName, string iterationKey, LoadSerializedObjectDelegate <T> loadObject) where T : class
        {
            T returnObject = default(T);

            // get the section
            CacheItemContainer cacheItemContainer = CreateSaveItemInstance(cacheItemName);
            string             cacheKey           = cacheItemContainer.CacheKey + iterationKey ?? string.Empty;

            if (_StaticCacheController.Enabled && cacheItemContainer.CacheItem.Enabled)
            {// use cache
                switch (cacheItemContainer.CacheMode)
                {
                case CacheMode.InProcess:

                    #region InProcess
                    returnObject = HttpRuntime.Cache[cacheKey] as T;
                    if (returnObject == null)
                    {
                        lock (ContinuousCacheAccessSynchronizationManager.CacheItemNameLocks[cacheItemName])
                        {
                            // check again in case the object was inserted into cache after the conditional statement but before the Monitor lock
                            returnObject = HttpRuntime.Cache[cacheKey] as T;

                            if (returnObject == null)
                            {    // get new object and cache it
                                #region debug
#if DEBUG
                                Trace.WriteLine(DebugConstants.DEBUG_PREFIX + "Item not found at cache");
#endif
                                #endregion

                                try { returnObject = loadObject.Invoke(); }
                                catch (Exception e) { throw new CachingException("An error occurred during the execution of the loadObject delegate. See the inner exception for further details.", e); }

                                if (returnObject != null)
                                {
                                    cacheItemContainer.LatestFetch = DateTime.UtcNow;

                                    HttpRuntime.Cache.Insert(
                                        cacheKey
                                        , returnObject
                                        , null
                                        , cacheItemContainer.ActualExpiryDate
                                        , System.Web.Caching.Cache.NoSlidingExpiration
                                        , cacheItemContainer.CacheItem.CacheItemPriority
                                        , null);

                                    #region debug
#if DEBUG
                                    Trace.WriteLine("\n" + DebugConstants.DEBUG_PREFIX + "\n*INPROCESS CACHE INSERT:\n*\t\t\tInserted new object into cache at " + cacheItemContainer.LatestFetch.ToString("HH:mm:ss.fff")
                                                    + "\n*\t\t\tActual expiry date: " + cacheItemContainer.ActualExpiryDate.ToString("HH:mm:ss.fff")
                                                    + "\n*\t\t\tInserted new stale key with expiry date: " + cacheItemContainer.SpecifiedExpiryDate.ToString("HH:mm:ss.fff")
                                                    + "\n*\t\t\tKey: " + cacheItemContainer.CacheKey
                                                    + "\n************************************************************************************************\n");
#endif
                                    #endregion
                                }

                                #region debug
#if DEBUG
                                Trace.WriteLine(DebugConstants.DEBUG_PREFIX + "Item inserted at normal cache call");
#endif
                                #endregion
                            }
                        }
                    }
                    else
                    {
                        if (cacheItemContainer.CacheItem.UseContinuousAccess &&
                            cacheItemContainer.IsInExtendedLifeSpan(DateTime.UtcNow))
                        {
                            #region debug
#if DEBUG
                            Trace.WriteLine(DebugConstants.DEBUG_PREFIX + "IsInExtendedLifeSpan at " + DateTime.UtcNow.ToString("HH:mm:ss.fff"));
#endif
                            #endregion

                            // we are in the extended lifespan, so we need to check whether we have to reload the object
                            ContinuousCacheAccessSynchronizationManager.TriggerAsynchronousFetch <T>(loadObject, cacheItemName, iterationKey, cacheItemContainer);
                        }
                    }
                    #endregion

                    break;

                case CacheMode.Memcached:
                case CacheMode.MemcachedProtocolBufferSerialization:

                    #region Memcached

                    returnObject = GetMemcachedObject <T>(cacheKey, cacheItemContainer.CacheMode);
                    if (returnObject == null)
                    {
                        lock (ContinuousCacheAccessSynchronizationManager.CacheItemNameLocks[cacheItemName])
                        {
                            // check again in case the object was inserted into cache after the conditional statement but before the Monitor lock
                            returnObject = GetMemcachedObject <T>(cacheKey, cacheItemContainer.CacheMode);

                            if (returnObject == null)
                            {    // get new object and cache it
                                #region debug
#if DEBUG
                                Trace.WriteLine(DebugConstants.DEBUG_PREFIX + "Item not found at cache");
#endif
                                #endregion

                                try { returnObject = loadObject.Invoke(); }
                                catch (Exception e) { throw new CachingException("An error occurred during the execution of the loadObject delegate. See the inner exception for further details.", e); }

                                if (returnObject != null)
                                {
                                    InsertMemcachedObject <T>(cacheItemContainer, returnObject);
                                }

                                #region debug
#if DEBUG
                                Trace.WriteLine(DebugConstants.DEBUG_PREFIX + "Item inserted at normal cache call");
#endif
                                #endregion
                            }
                        }
                    }
                    else
                    {
                        #region Note on Memcached locking and synchronization

                        /* Important note on memcached caching:
                         *
                         * trying to accomplish thread safety via Memcached.Add is not thread safe and may not work as expected. Memcached.Add should only
                         * add an object if it does not exist yet, however, you never know when memcached actually inserts the data. If you write
                         * code like ->
                         *
                         *    int i = 5;
                         *    DistributedCache.Insert("MyKey", 5);
                         *    int cachedValue = DistributedCache.Get<int>("MyKey");
                         *
                         * it is not guaranteed that "cachedValue" will be 5. During testing against a dev machine with memcache running as a
                         * Windows XP service, it took up to 600ms until a value was actually retrievable after the insert. Here s a table with
                         * tests which were run against the dev machine:
                         *
                         * ,--.       ,---.            Add Test success percentage with 1 milliseconds: 0.3942
                         * /    '.    /     \           Add Test success percentage with 26 milliseconds: 0.416
                         \  ;                  Add Test success percentage with 51 milliseconds: 0.4408
                         \-|                  Add Test success percentage with 76 milliseconds: 0.4804
                         \ (o o)      (/         Add Test success percentage with 101 milliseconds: 0.555
                         \ /'v'     ,-'          Add Test success percentage with 126 milliseconds: 0.5548
                         \ ,------/ >< \---'             Add Test success percentage with 151 milliseconds: 0.5556
                         \ /)     ;  --  :                Add Test success percentage with 176 milliseconds: 0.5562
                         \ ,---| ---- |--.             Add Test success percentage with 201 milliseconds: 0.6018
                         \ ;    | ---- |   :            Add Test success percentage with 226 milliseconds: 0.6232
                         \ (|  ,-| ---- |-. |)           Add Test success percentage with 251 milliseconds: 0.6
                         | /| ---- |\ |             Add Test success percentage with 276 milliseconds: 0.6132
                         |/ | ---- | \|             Add Test success percentage with 301 milliseconds: 0.6906
                         \  : ---- ;  |             Add Test success percentage with 326 milliseconds: 0.738
                         \  \ -- /  /              Add Test success percentage with 351 milliseconds: 0.7476
                         \ ;   \  /  :               Add Test success percentage with 376 milliseconds: 0.76
                         \ /   / \/ \  \              Add Test success percentage with 401 milliseconds: 0.7996
                         \ /)           (\             Add Test success percentage with 426 milliseconds: 0.8068
                         \      Add Test success percentage with 451 milliseconds: 0.848
                         \      Add Test success percentage with 476 milliseconds: 0.8486
                         \      Add Test success percentage with 501 milliseconds: 0.86
                         \      Add Test success percentage with 526 milliseconds: 0.9284
                         \      Add Test success percentage with 551 milliseconds: 0.981
                         \      Add Test success percentage with 576 milliseconds: 0.9554
                         \      Add Test success percentage with 601 milliseconds: 1
                         \      Add Test success percentage with 626 milliseconds: 1
                         \      Add Test success percentage with 651 milliseconds: 1
                         \      Add Test success percentage with 676 milliseconds: 1
                         \      Add Test success percentage with 701 milliseconds: 1
                         \      Add Test success percentage with 726 milliseconds: 1
                         \      Add Test success percentage with 751 milliseconds: 1
                         \      Add Test success percentage with 776 milliseconds: 1
                         \      Add Test success percentage with 801 milliseconds: 1
                         \      Add Test success percentage with 826 milliseconds: 1
                         \      Add Test success percentage with 851 milliseconds: 1
                         \      Add Test success percentage with 876 milliseconds: 1
                         \      Add Test success percentage with 901 milliseconds: 1
                         \      Add Test success percentage with 926 milliseconds: 1
                         \      Add Test success percentage with 951 milliseconds: 1
                         \      Add Test success percentage with 976 milliseconds: 1
                         \
                         \ However, this is still better than aquiring a lock from a database table which would be thread safe but cause an enormous
                         \ amount of SQL traffic. Using a windows service on a dedicated machine which handles the locking would be best but it also
                         \ eats a lot of network bandwidth.
                         \
                         */
                        #endregion

                        if (cacheItemContainer.CacheItem.UseContinuousAccess &&
                            DistributedCache.Get <object>(cacheItemContainer.MemcachedStaleCacheKey) == null)
                        {
                            #region debug
#if DEBUG
                            Trace.WriteLine(DebugConstants.DEBUG_PREFIX + "IsInExtendedLifeSpan at " + DateTime.UtcNow.ToString("HH:mm:ss.fff"));
#endif
                            #endregion

                            // we are in the extended lifespan, so we need to check whether we have to reload the object
                            ContinuousCacheAccessSynchronizationManager.TriggerAsynchronousFetch <T>(loadObject, cacheItemName, iterationKey, cacheItemContainer);
                        }
                    }
                    #endregion

                    break;
                }
            }
            else
            {// don't use cache
                try { returnObject = loadObject.Invoke(); }
                catch (Exception e) { throw new CachingException("An error occurred during the execution of the loadObject delegate. See the inner exception for further details.", e); }
            }

            return(returnObject);
        }