コード例 #1
0
        /// <summary>
        /// Tries to get the result of the <see cref="FetchingExecutor{TReturn}"/> from the cache. If it can't it starts a new prefetch thread in
        /// the background.
        /// </summary>
        /// <param name="del">
        /// A <see cref="FetchingExecutor{TReturn}"/> which will be prefetched by the class.
        /// </param>
        /// <param name="cacheTime">
        /// The number of seconds of cache life as a <see cref="System.Int32"/>/
        /// </param>
        /// <param name="prefetchCacheOptions">
        /// A <see cref="PrefetchCacheOptions"/> flags, which specify the behavior of this cache.
        /// </param>
        /// <param name="args">
        /// A series of <see cref="System.Object"/>s which represent the parameters upon which the <see cref="FetchingExecutor{TReturn}"/>
        /// operates. The same delegate with different parameters will be cached separately.
        /// </param>
        /// <returns>
        /// A TReturn, the result of the cache lookup.
        /// </returns>
        public static TReturn Get <TReturn>(FetchingExecutor <TReturn> del, int cacheTime, PrefetchCacheOptions prefetchCacheOptions,
                                            params object[] args)
        {
            if (cacheTime > 0)
            {
                StackTrace    trace     = new StackTrace(1, false);
                MethodBase    caller    = trace.GetFrame(0).GetMethod();
                StringBuilder invokeSig =
                    new StringBuilder(caller.DeclaringType.FullName.GetHashCode().ToString("X", CultureInfo.InvariantCulture));
                invokeSig.Append(caller.Name.GetHashCode().ToString("X", CultureInfo.InvariantCulture));
                invokeSig.AppendFormat(" {0}.{1}", caller.DeclaringType.FullName.Split(',')[0], caller.Name);
                foreach (object o in args)
                {
                    invokeSig.AppendFormat(CultureInfo.InvariantCulture, " <{0}>", o.GetHashCode());
                    Console.WriteLine("{0} - {1}", o.GetType().FullName, o);
                }

                return(PrefetchCacheController.GetFromCache(invokeSig.ToString(), del, cacheTime, prefetchCacheOptions));
            }

            return(del());
        }
コード例 #2
0
        /// <summary>
        /// Creates a new instance of <see cref="PrefetchCacheAgent{TReturn}"/>
        /// </summary>
        /// <param name="name">
        /// The name of this agent in cache
        /// </param>
        /// <param name="del">
        /// A <see cref="FetchingExecutor{TReturn}"/> which will be executed repeatedly each interval
        /// to refresh the content.
        /// </param>
        /// <param name="cacheTime">
        /// The length of time between attempts to refresh the content
        /// </param>
        public PrefetchCacheAgent(string name, FetchingExecutor <TReturn> del, int cacheTime)
        {
#if DEBUG
            sig = name;
            Log.Instance.AddFormat("PrefetchCacheAgent - ctor invoked, id <{0}>, spawning...", sig);
#endif
            myExecutor     = del;
            this.cacheTime = cacheTime;
            this.name      = name;

            content = new PrefetchCacheContent <TReturn>();
            // Spawn Update Thread
            timerFunction = new PrefetchCacheTimer(10);

            timerFunction.Fetching += timerFunction_OnFetching;
            timerFunction.Idling   += timerFunction_OnIdling;

            TimerCallback timerDelegate = timerFunction.Fetch;
            timer = new Timer(timerDelegate, null, 0, cacheTime * 1000);
#if DEBUG
            Log.Instance.AddFormat("PrefetchCacheAgent - ...timer for '{0}' spawned!", sig);
#endif
        }
コード例 #3
0
        internal static TReturn GetFromCache <TReturn>(string cacheName, FetchingExecutor <TReturn> del, int cacheTime,
                                                       PrefetchCacheOptions prefetchCacheOptions)
        {
            if (!agents.ContainsKey(cacheName))
            {
                lock (agents)
                {
                    if (!agents.ContainsKey(cacheName))
                    {
#if DEBUG
                        Log.Instance.AddFormat("GetFromCache: Method '{0}', Creating Agent ", cacheName);
#endif
                        agents[cacheName]         = new PrefetchCacheAgent <TReturn>(cacheName, del, cacheTime);
                        agents[cacheName].Idling += agent_OnIdling;
                    }
                }
            }

            IPrefetchCacheAgent agent = agents[cacheName];

            // If we don't have the content in cache, we either return null or wait for it to be retrieved
            if (!agent.HasContent)
            {
                // If we can, we return null and don't keep the caller waiting
                if ((prefetchCacheOptions & PrefetchCacheOptions.AllowNoResult) != 0)
                {
#if DEBUG
                    Log.Instance.AddFormat("GetFromCache: Method '{0}', Returning null (allowed)", cacheName);
#endif
                    return(default(TReturn));
                    //return new ReturnMessage(null, null, 0, methodMessage.LogicalCallContext, methodMessage);
                }

#if DEBUG
                Log.Instance.Add("Before wait for content (null check)");
#endif
                // We wait for the agent to retrieve the content
                agent.WaitForNotNullContent(10000);

                // If we, yet again, don't have content here, we must return an exception
                if (!agent.HasContent)
                {
                    //return new ReturnMessage(
                    throw new ContentNullException("Could not retrieve content from cache.", agent.Exception);
                    //, methodMessage);
                }
                //return agent.Content.ReturnMessage;
            }

            // If caller doesn't care about expired items, we just give what we have
            // Or, if the content is up-to-date, we return it
            if ((prefetchCacheOptions & PrefetchCacheOptions.AllowExpired) != 0 || agent.Content.ExpiryDate >= DateTime.Now)
            {
#if DEBUG
                Log.Instance.AddFormat("GetFromCache: Method '{0}', Returning unchecked expiry (allowed)", cacheName);
#endif
                return((TReturn)agent.Content.ReturnMessage);
            }

            // The content must be up-to-date, but it's old.
            // We wait for new content

#if DEBUG
            Log.Instance.AddFormat("Before wait for content (expiry check) {0:s:fffff}, {1:s:fffff}", agent.Content.ExpiryDate,
                                   DateTime.Now);
#endif
            agent.WaitForFreshContent(10000);
#if DEBUG
            Log.Instance.AddFormat("After wait for content (expiry check) {0:s:fffff}, {1:s:fffff}", agent.Content.ExpiryDate,
                                   DateTime.Now);
#endif

            // If the content is expired we are DOOMED and we must return an exception
            if (agent.Content.ExpiryDate < DateTime.Now)
            {
                //return new ReturnMessage(
                throw new ContentExpiredException("Content in cache has expired.", agent.Exception);
                //, methodMessage);
            }
#if DEBUG
            Log.Instance.AddFormat("GetFromCache: Method '{0}', Returning real", cacheName);
#endif

            // All is well, return the content.

            return((TReturn)agent.Content.ReturnMessage);
        }