Пример #1
0
        public Task UnregisterManyAsync(List <ActivationAddress> addresses)
        {
            unregistrationsManyIssued.Increment();
            return(Task.WhenAll(
                       addresses.GroupBy(a => CalculateTargetSilo(a.Grain))
                       .Select(g =>
            {
                if (g.Key == null)
                {
                    // We don't know about any other silos, and we're stopping, so throw
                    throw new InvalidOperationException("Grain directory is stopping");
                }

                foreach (var addr in g)
                {
                    InvalidateCacheEntry(addr);
                }

                if (MyAddress.Equals(g.Key))
                {
                    // if I am the owner, remove the old activation locally
                    foreach (var addr in g)
                    {
                        UnregistrationsLocal.Increment();
                        DirectoryPartition.RemoveActivation(addr.Grain, addr.Activation, true);
                    }
                    return TaskDone.Done;
                }

                UnregistrationsManyRemoteSent.Increment();
                // otherwise, notify the owner
                return GetDirectoryReference(g.Key).UnregisterMany(g.ToList(), NUM_RETRIES);
            })));
        }
Пример #2
0
        /// Adjust local cache following the removal of a silo by droping:
        /// 1) entries that point to activations located on the removed silo
        /// 2) entries for grains that are now owned by this silo (me)
        /// 3) entries for grains that were owned by this removed silo - we currently do NOT do that.
        ///     If we did 3, we need to do that BEFORE we change the membershipRingList (based on old Membership).
        ///     We don't do that since first cache refresh handles that.
        ///     Second, since Membership events are not guaranteed to be ordered, we may remove a cache entry that does not really point to a failed silo.
        ///     To do that properly, we need to store for each cache entry who was the directory owner that registered this activation (the original partition owner).
        protected void AdjustLocalCache(SiloAddress removedSilo)
        {
            // remove all records of activations located on the removed silo
            foreach (Tuple <GrainId, List <Tuple <SiloAddress, ActivationId> >, int> tuple in DirectoryCache.KeyValues)
            {
                // 2) remove entries owned by me (they should be retrieved from my directory partition)
                if (MyAddress.Equals(CalculateTargetSilo(tuple.Item1)))
                {
                    DirectoryCache.Remove(tuple.Item1);
                }

                // 1) remove entries that point to activations located on the removed silo
                if (tuple.Item2.RemoveAll(tuple2 => tuple2.Item1.Equals(removedSilo)) <= 0)
                {
                    continue;
                }

                if (tuple.Item2.Count > 0)
                {
                    DirectoryCache.AddOrUpdate(tuple.Item1, tuple.Item2, tuple.Item3);
                }
                else
                {
                    DirectoryCache.Remove(tuple.Item1);
                }
            }
        }
Пример #3
0
        /// Adjust local cache following the removal of a silo by droping:
        /// 1) entries that point to activations located on the removed silo
        /// 2) entries for grains that are now owned by this silo (me)
        /// 3) entries for grains that were owned by this removed silo - we currently do NOT do that.
        ///     If we did 3, we need to do that BEFORE we change the membershipRingList (based on old Membership).
        ///     We don't do that since first cache refresh handles that.
        ///     Second, since Membership events are not guaranteed to be ordered, we may remove a cache entry that does not really point to a failed silo.
        ///     To do that properly, we need to store for each cache entry who was the directory owner that registered this activation (the original partition owner).
        protected void AdjustLocalCache(SiloAddress removedSilo)
        {
            // remove all records of activations located on the removed silo
            foreach (Tuple <GrainId, IReadOnlyList <Tuple <SiloAddress, ActivationId> >, int> tuple in DirectoryCache.KeyValues)
            {
                // 2) remove entries now owned by me (they should be retrieved from my directory partition)
                if (MyAddress.Equals(CalculateTargetSilo(tuple.Item1)))
                {
                    DirectoryCache.Remove(tuple.Item1);
                }

                // 1) remove entries that point to activations located on the removed silo
                RemoveActivations(DirectoryCache, tuple.Item1, tuple.Item2, tuple.Item3, t => t.Item1.Equals(removedSilo));
            }
        }
Пример #4
0
        /// <summary>
        /// For testing purposes only.
        /// Returns the directory information held by the local silo for the provided grain ID.
        /// The result will be null if no information is held.
        /// </summary>
        /// <param name="grain"></param>
        /// <param name="isPrimary"></param>
        /// <returns></returns>
        public List <ActivationAddress> GetLocalDataForGrain(GrainId grain, out bool isPrimary)
        {
            var primary = CalculateTargetSilo(grain);
            List <ActivationAddress> backupData = HandoffManager.GetHandedOffInfo(grain);

            if (MyAddress.Equals(primary))
            {
                log.Assert(ErrorCode.DirectoryBothPrimaryAndBackupForGrain, backupData == null,
                           "Silo contains both primary and backup directory data for grain " + grain);
                isPrimary = true;
                return(GetLocalDirectoryData(grain));
            }

            isPrimary = false;
            return(backupData);
        }
Пример #5
0
        /// Adjust local cache following the removal of a silo by dropping:
        /// 1) entries that point to activations located on the removed silo
        /// 2) entries for grains that are now owned by this silo (me)
        /// 3) entries for grains that were owned by this removed silo - we currently do NOT do that.
        ///     If we did 3, we need to do that BEFORE we change the membershipRingList (based on old Membership).
        ///     We don't do that since first cache refresh handles that.
        ///     Second, since Membership events are not guaranteed to be ordered, we may remove a cache entry that does not really point to a failed silo.
        ///     To do that properly, we need to store for each cache entry who was the directory owner that registered this activation (the original partition owner).
        protected void AdjustLocalCache(SiloAddress silo, bool dead)
        {
            // remove all records of activations located on the removed silo
            foreach (var tuple in DirectoryCache.KeyValues)
            {
                var activationAddress = tuple.ActivationAddress;

                // 2) remove entries now owned by me (they should be retrieved from my directory partition)
                if (MyAddress.Equals(CalculateGrainDirectoryPartition(activationAddress.GrainId)))
                {
                    DirectoryCache.Remove(activationAddress.GrainId);
                }

                // 1) remove entries that point to activations located on the removed silo
                // For dead silos, remove any activation registered to that silo or one of its predecessors.
                // For new silos, remove any activation registered to one of its predecessors.
                if (activationAddress.SiloAddress.IsPredecessorOf(silo) || (activationAddress.SiloAddress.Equals(silo) && dead))
                {
                    DirectoryCache.Remove(activationAddress.GrainId);
                }
            }
        }