Пример #1
0
        protected override void Run()
        {
            while (router.Running)
            {
                // Run through all cache entries and do the following:
                // 1. If the entry is not expired, skip it
                // 2. If the entry is expired and was not accessed in the last time interval -- throw it away
                // 3. If the entry is expired and was accessed in the last time interval, put into "fetch-batch-requests" list

                // At the end of the process, fetch batch requests for entries that need to be refreshed

                // Upon receiving refreshing answers, if the entry was not changed, double its expiration timer.
                // If it was changed, update the cache and reset the expiration timer.

                // this dictionary holds a map between a silo address and the list of grains that need to be refreshed
                var fetchInBatchList = new Dictionary <SiloAddress, List <GrainId> >();

                // get the list of cached grains


                // for debug only
                int cnt1 = 0, cnt2 = 0, cnt3 = 0, cnt4 = 0;

                // run through all cache entries
                var enumerator = cache.GetStoredEntries();
                while (enumerator.MoveNext())
                {
                    var     pair  = enumerator.Current;
                    GrainId grain = pair.Key;
                    var     entry = pair.Value;

                    SiloAddress owner = router.CalculateGrainDirectoryPartition(grain);
                    if (owner == null) // Null means there's no other silo and we're shutting down, so skip this entry
                    {
                        continue;
                    }

                    if (owner.Equals(router.MyAddress))
                    {
                        // we found our owned entry in the cache -- it is not supposed to happen unless there were
                        // changes in the membership
                        Log.Warn(ErrorCode.Runtime_Error_100185, "Grain {grain} owned by {owner} was found in the cache of {owner}", grain, owner, owner);
                        cache.Remove(grain);
                        cnt1++;                             // for debug
                    }
                    else
                    {
                        if (entry == null)
                        {
                            // 0. If the entry was deleted in parallel, presumably due to cleanup after silo death
                            cache.Remove(grain);            // for debug
                            cnt3++;
                        }
                        else if (!entry.IsExpired())
                        {
                            // 1. If the entry is not expired, skip it
                            cnt2++;                         // for debug
                        }
                        else if (entry.NumAccesses == 0)
                        {
                            // 2. If the entry is expired and was not accessed in the last time interval -- throw it away
                            cache.Remove(grain);            // for debug
                            cnt3++;
                        }
                        else
                        {
                            // 3. If the entry is expired and was accessed in the last time interval, put into "fetch-batch-requests" list
                            if (!fetchInBatchList.ContainsKey(owner))
                            {
                                fetchInBatchList[owner] = new List <GrainId>();
                            }
                            fetchInBatchList[owner].Add(grain);
                            // And reset the entry's access count for next time
                            entry.NumAccesses = 0;
                            cnt4++;                         // for debug
                        }
                    }
                }

                if (Log.IsEnabled(LogLevel.Trace))
                {
                    Log.Trace("Silo {0} self-owned (and removed) {1}, kept {2}, removed {3} and tries to refresh {4} grains", router.MyAddress, cnt1, cnt2, cnt3, cnt4);
                }

                // send batch requests
                SendBatchCacheRefreshRequests(fetchInBatchList);

                ProduceStats();

                // recheck every X seconds (Consider making it a configurable parameter)
                Thread.Sleep(SLEEP_TIME_BETWEEN_REFRESHES);
            }
        }
        protected override async Task Run()
        {
            while (router.Running)
            {
                // Run through all cache entries and do the following:
                // 1. If the entry is not expired, skip it
                // 2. If the entry is expired and was not accessed in the last time interval -- throw it away
                // 3. If the entry is expired and was accessed in the last time interval, put into "fetch-batch-requests" list

                // At the end of the process, fetch batch requests for entries that need to be refreshed

                // Upon receiving refreshing answers, if the entry was not changed, double its expiration timer.
                // If it was changed, update the cache and reset the expiration timer.

                // this dictionary holds a map between a silo address and the list of grains that need to be refreshed
                var fetchInBatchList = new Dictionary <SiloAddress, List <GrainId> >();

                // get the list of cached grains


                // for debug only
                int cnt1 = 0, cnt2 = 0, cnt3 = 0, cnt4 = 0;

                // run through all cache entries
                var enumerator = cache.GetStoredEntries();
                while (enumerator.MoveNext())
                {
                    var     pair  = enumerator.Current;
                    GrainId grain = pair.Key;
                    var     entry = pair.Value;

                    SiloAddress owner = router.CalculateGrainDirectoryPartition(grain);
                    if (owner == null) // Null means there's no other silo and we're shutting down, so skip this entry
                    {
                        continue;
                    }

                    if (entry == null)
                    {
                        // 0. If the entry was deleted in parallel, presumably due to cleanup after silo death
                        cache.Remove(grain);            // for debug
                        cnt3++;
                    }
                    else if (!entry.IsExpired())
                    {
                        // 1. If the entry is not expired, skip it
                        cnt2++;                         // for debug
                    }
                    else if (entry.NumAccesses == 0)
                    {
                        // 2. If the entry is expired and was not accessed in the last time interval -- throw it away
                        cache.Remove(grain);            // for debug
                        cnt3++;
                    }
                    else
                    {
                        // 3. If the entry is expired and was accessed in the last time interval, put into "fetch-batch-requests" list
                        if (!fetchInBatchList.TryGetValue(owner, out var list))
                        {
                            fetchInBatchList[owner] = list = new List <GrainId>();
                        }
                        list.Add(grain);
                        // And reset the entry's access count for next time
                        entry.NumAccesses = 0;
                        cnt4++;                         // for debug
                    }
                }

                if (Log.IsEnabled(LogLevel.Trace))
                {
                    Log.LogTrace(
                        "Silo {SiloAddress} self-owned (and removed) {OwnedAndRemovedCount}, kept {KeptCount}, removed {RemovedCount} and tried to refresh {RefreshedCount} grains",
                        router.MyAddress,
                        cnt1,
                        cnt2,
                        cnt3,
                        cnt4);
                }

                // send batch requests
                SendBatchCacheRefreshRequests(fetchInBatchList);

                ProduceStats();

                // recheck every X seconds (Consider making it a configurable parameter)
                await Task.Delay(SLEEP_TIME_BETWEEN_REFRESHES);
            }
        }