Ejemplo n.º 1
0
        private static readonly TimeSpan RETRY_DELAY = TimeSpan.FromSeconds(5); // Pause 5 seconds between forwards to let the membership directory settle down

        internal RemoteGrainDirectory(LocalGrainDirectory r, GrainId id)
            : base(id, r.MyAddress)
        {
            router = r;
            partition = r.DirectoryPartition;
            logger = TraceLogger.GetLogger("Orleans.GrainDirectory.CacheValidator", TraceLogger.LoggerType.Runtime);
        }
 public GlobalSingleInstanceRegistrar(GrainDirectoryPartition partition, Logger logger, GlobalSingleInstanceActivationMaintainer gsiActivationMaintainer, int numRetries)
      
 {
     this.directoryPartition = partition;
     this.logger = logger;
     this.gsiActivationMaintainer = gsiActivationMaintainer;
     this.numRetries = numRetries;
 }
Ejemplo n.º 3
0
 public ClusterLocalRegistrar(GrainDirectoryPartition partition)
 {
     directoryPartition = partition;
 }
Ejemplo n.º 4
0
        /// <summary>
        /// Runs through all entries in the partition and moves/copies (depending on the given flag) the
        /// entries satisfying the given predicate into a new partition.
        /// This method is supposed to be used by handoff manager to update the partitions when the system view (set of live silos) changes.
        /// </summary>
        /// <param name="predicate">filter predicate (usually if the given grain is owned by particular silo)</param>
        /// <param name="modifyOrigin">flag controling whether the source partition should be modified (i.e., the entries should be moved or just copied) </param>
        /// <returns>new grain directory partition containing entries satisfying the given predicate</returns>
        internal GrainDirectoryPartition Split(Predicate<GrainId> predicate, bool modifyOrigin)
        {
            var newDirectory = new GrainDirectoryPartition();

            if (modifyOrigin)
            {
                // SInce we use the "pairs" list to modify the underlying collection below, we need to turn it into an actual list here
                List<KeyValuePair<GrainId, IGrainInfo>> pairs;
                lock (lockable)
                {
                    pairs = partitionData.Where(pair => predicate(pair.Key)).ToList();
                }

                foreach (var pair in pairs)
                {
                    newDirectory.partitionData.Add(pair.Key, pair.Value);
                }

                lock (lockable)
                {
                    foreach (var pair in pairs)
                    {
                        partitionData.Remove(pair.Key);
                    }
                }
            }
            else
            {
                lock (lockable)
                {
                    foreach (var pair in partitionData.Where(pair => predicate(pair.Key)))
                    {
                        newDirectory.partitionData.Add(pair.Key, pair.Value);
                    }
                }
            }

            return newDirectory;
        }
Ejemplo n.º 5
0
 /// <summary>
 /// Merges one partition into another, asuuming partitions are disjoint.
 /// This method is supposed to be used by handoff manager to update the partitions when the system view (set of live silos) changes.
 /// </summary>
 /// <param name="other"></param>
 internal void Merge(GrainDirectoryPartition other)
 {
     lock (lockable)
     {
         foreach (var pair in other.partitionData)
         {
             if (partitionData.ContainsKey(pair.Key))
             {
                 if (log.IsVerbose) log.Verbose("While merging two disjoint partitions, same grain " + pair.Key + " was found in both partitions");
                 partitionData[pair.Key].Merge(pair.Key, pair.Value);
             }
             else
             {
                 partitionData.Add(pair.Key, pair.Value);
             }
         }
     }
 }
        internal void AcceptHandoffPartition(SiloAddress source, Dictionary<GrainId, IGrainInfo> partition, bool isFullCopy)
        {
            if (logger.IsVerbose) logger.Verbose("Got request to register " + (isFullCopy ? "FULL" : "DELTA") + " directory partition with " + partition.Count + " elements from " + source);

            if (!directoryPartitionsMap.ContainsKey(source))
            {
                if (!isFullCopy)
                {
                    logger.Warn(ErrorCode.DirectoryUnexpectedDelta, 
                        String.Format("Got delta of the directory partition from silo {0} (Membership status {1}) while not holding a full copy. Membership active cluster size is {2}",
                            source, localDirectory.Membership.GetApproximateSiloStatus(source),
                            localDirectory.Membership.GetApproximateSiloStatuses(true).Count));
                }

                directoryPartitionsMap[source] = new GrainDirectoryPartition();
            }

            if (isFullCopy)
            {
                directoryPartitionsMap[source].Set(partition);
            }
            else
            {
                directoryPartitionsMap[source].Update(partition);
            }
        }
Ejemplo n.º 7
0
        public LocalGrainDirectory(Silo silo)
        {
            log = TraceLogger.GetLogger("Orleans.GrainDirectory.LocalGrainDirectory");

            MyAddress = silo.LocalMessageCenter.MyAddress;
            Scheduler = silo.LocalScheduler;
            membershipRingList = new List<SiloAddress>();
            membershipCache = new HashSet<SiloAddress>();

            silo.OrleansConfig.OnConfigChange("Globals/Caching", () =>
            {
                lock (membershipCache)
                {
                    DirectoryCache = GrainDirectoryCacheFactory<List<Tuple<SiloAddress, ActivationId>>>.CreateGrainDirectoryCache(silo.GlobalConfig);
                }
            });
            maintainer = GrainDirectoryCacheFactory<List<Tuple<SiloAddress, ActivationId>>>.CreateGrainDirectoryCacheMaintainer(this, DirectoryCache);

            if (silo.GlobalConfig.SeedNodes.Count > 0)
            {
                seed = silo.GlobalConfig.SeedNodes.Contains(MyAddress.Endpoint) ? MyAddress : SiloAddress.New(silo.GlobalConfig.SeedNodes[0], 0);
            }

            stopPreparationResolver = new TaskCompletionSource<bool>();
            DirectoryPartition = new GrainDirectoryPartition();
            HandoffManager = new GrainDirectoryHandoffManager(this, silo.GlobalConfig);

            RemGrainDirectory = new RemoteGrainDirectory(this, Constants.DirectoryServiceId);
            CacheValidator = new RemoteGrainDirectory(this, Constants.DirectoryCacheValidatorId);

            // add myself to the list of members
            AddServer(MyAddress);

            Func<SiloAddress, string> siloAddressPrint = (SiloAddress addr) => 
                String.Format("{0}/{1:X}", addr.ToLongString(), addr.GetConsistentHashCode());
            
            localLookups = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_LOOKUPS_LOCAL_ISSUED);
            localSuccesses = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_LOOKUPS_LOCAL_SUCCESSES);
            fullLookups = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_LOOKUPS_FULL_ISSUED);

            RemoteLookupsSent = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_LOOKUPS_REMOTE_SENT);
            RemoteLookupsReceived = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_LOOKUPS_REMOTE_RECEIVED);

            LocalDirectoryLookups = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_LOOKUPS_LOCALDIRECTORY_ISSUED);
            LocalDirectorySuccesses = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_LOOKUPS_LOCALDIRECTORY_SUCCESSES);

            cacheLookups = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_LOOKUPS_CACHE_ISSUED);
            cacheSuccesses = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_LOOKUPS_CACHE_SUCCESSES);
            StringValueStatistic.FindOrCreate(StatisticNames.DIRECTORY_LOOKUPS_CACHE_HITRATIO, () =>
                {
                    long delta1, delta2;
                    long curr1 = cacheSuccesses.GetCurrentValueAndDelta(out delta1);
                    long curr2 = cacheLookups.GetCurrentValueAndDelta(out delta2);
                    return String.Format("{0}, Delta={1}", 
                        (curr2 != 0 ? (float)curr1 / (float)curr2 : 0)
                        ,(delta2 !=0 ? (float)delta1 / (float)delta2 : 0));
                });

            CacheValidationsSent = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_VALIDATIONS_CACHE_SENT);
            CacheValidationsReceived = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_VALIDATIONS_CACHE_RECEIVED);

            registrationsIssued = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_REGISTRATIONS_ISSUED);
            RegistrationsLocal = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_REGISTRATIONS_LOCAL);
            RegistrationsRemoteSent = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_REGISTRATIONS_REMOTE_SENT);
            RegistrationsRemoteReceived = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_REGISTRATIONS_REMOTE_RECEIVED);
            registrationsSingleActIssued = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_REGISTRATIONS_SINGLE_ACT_ISSUED);
            RegistrationsSingleActLocal = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_REGISTRATIONS_SINGLE_ACT_LOCAL);
            RegistrationsSingleActRemoteSent = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_REGISTRATIONS_SINGLE_ACT_REMOTE_SENT);
            RegistrationsSingleActRemoteReceived = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_REGISTRATIONS_SINGLE_ACT_REMOTE_RECEIVED);
            unregistrationsIssued = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_UNREGISTRATIONS_ISSUED);
            UnregistrationsLocal = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_UNREGISTRATIONS_LOCAL);
            UnregistrationsRemoteSent = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_UNREGISTRATIONS_REMOTE_SENT);
            UnregistrationsRemoteReceived = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_UNREGISTRATIONS_REMOTE_RECEIVED);
            unregistrationsManyIssued = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_UNREGISTRATIONS_MANY_ISSUED);
            UnregistrationsManyRemoteSent = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_UNREGISTRATIONS_MANY_REMOTE_SENT);
            UnregistrationsManyRemoteReceived = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_UNREGISTRATIONS_MANY_REMOTE_RECEIVED);

            directoryPartitionCount = IntValueStatistic.FindOrCreate(StatisticNames.DIRECTORY_PARTITION_SIZE, () => DirectoryPartition.Count);
            IntValueStatistic.FindOrCreate(StatisticNames.DIRECTORY_RING_MYPORTION_RINGDISTANCE, () => RingDistanceToSuccessor());
            FloatValueStatistic.FindOrCreate(StatisticNames.DIRECTORY_RING_MYPORTION_RINGPERCENTAGE, () => (((float)RingDistanceToSuccessor()) / ((float)(int.MaxValue * 2L))) * 100);
            FloatValueStatistic.FindOrCreate(StatisticNames.DIRECTORY_RING_MYPORTION_AVERAGERINGPERCENTAGE, () => membershipRingList.Count == 0 ? 0 : ((float)100 / (float)membershipRingList.Count));
            IntValueStatistic.FindOrCreate(StatisticNames.DIRECTORY_RING_RINGSIZE, () => membershipRingList.Count);
            StringValueStatistic.FindOrCreate(StatisticNames.DIRECTORY_RING, () =>
                {
                    lock (membershipCache)
                    {
                        return Utils.EnumerableToString(membershipRingList, siloAddressPrint);
                    }
                });
            StringValueStatistic.FindOrCreate(StatisticNames.DIRECTORY_RING_PREDECESSORS, () => Utils.EnumerableToString(FindPredecessors(MyAddress, 1), siloAddressPrint));
            StringValueStatistic.FindOrCreate(StatisticNames.DIRECTORY_RING_SUCCESSORS, () => Utils.EnumerableToString(FindSuccessors(MyAddress, 1), siloAddressPrint));
        }
Ejemplo n.º 8
0
 public ClusterLocalRegistrar(GrainDirectoryPartition partition)
 {
     directoryPartition = partition;
 }
Ejemplo n.º 9
0
 public ClusterLocalRegistrar(LocalGrainDirectory directory)
 {
     directoryPartition = directory.DirectoryPartition;
 }
Ejemplo n.º 10
0
        public LocalGrainDirectory(Silo silo)
        {
            log = TraceLogger.GetLogger("Orleans.GrainDirectory.LocalGrainDirectory");

            MyAddress          = silo.LocalMessageCenter.MyAddress;
            Scheduler          = silo.LocalScheduler;
            membershipRingList = new List <SiloAddress>();
            membershipCache    = new HashSet <SiloAddress>();

            silo.OrleansConfig.OnConfigChange("Globals/Caching", () =>
            {
                lock (membershipCache)
                {
                    DirectoryCache = GrainDirectoryCacheFactory <List <Tuple <SiloAddress, ActivationId> > > .CreateGrainDirectoryCache(silo.GlobalConfig);
                }
            });
            maintainer = GrainDirectoryCacheFactory <List <Tuple <SiloAddress, ActivationId> > > .CreateGrainDirectoryCacheMaintainer(this, DirectoryCache);

            if (silo.GlobalConfig.SeedNodes.Count > 0)
            {
                seed = silo.GlobalConfig.SeedNodes.Contains(MyAddress.Endpoint) ? MyAddress : SiloAddress.New(silo.GlobalConfig.SeedNodes[0], 0);
            }

            stopPreparationResolver = new TaskCompletionSource <bool>();
            DirectoryPartition      = new GrainDirectoryPartition();
            HandoffManager          = new GrainDirectoryHandoffManager(this, silo.GlobalConfig);

            RemGrainDirectory = new RemoteGrainDirectory(this, Constants.DirectoryServiceId);
            CacheValidator    = new RemoteGrainDirectory(this, Constants.DirectoryCacheValidatorId);

            // add myself to the list of members
            AddServer(MyAddress);

            Func <SiloAddress, string> siloAddressPrint = (SiloAddress addr) =>
                                                          String.Format("{0}/{1:X}", addr.ToLongString(), addr.GetConsistentHashCode());

            localLookups   = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_LOOKUPS_LOCAL_ISSUED);
            localSuccesses = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_LOOKUPS_LOCAL_SUCCESSES);
            fullLookups    = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_LOOKUPS_FULL_ISSUED);

            RemoteLookupsSent     = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_LOOKUPS_REMOTE_SENT);
            RemoteLookupsReceived = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_LOOKUPS_REMOTE_RECEIVED);

            LocalDirectoryLookups   = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_LOOKUPS_LOCALDIRECTORY_ISSUED);
            LocalDirectorySuccesses = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_LOOKUPS_LOCALDIRECTORY_SUCCESSES);

            cacheLookups   = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_LOOKUPS_CACHE_ISSUED);
            cacheSuccesses = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_LOOKUPS_CACHE_SUCCESSES);
            StringValueStatistic.FindOrCreate(StatisticNames.DIRECTORY_LOOKUPS_CACHE_HITRATIO, () =>
            {
                long delta1, delta2;
                long curr1 = cacheSuccesses.GetCurrentValueAndDelta(out delta1);
                long curr2 = cacheLookups.GetCurrentValueAndDelta(out delta2);
                return(String.Format("{0}, Delta={1}",
                                     (curr2 != 0 ? (float)curr1 / (float)curr2 : 0)
                                     , (delta2 != 0 ? (float)delta1 / (float)delta2 : 0)));
            });

            CacheValidationsSent     = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_VALIDATIONS_CACHE_SENT);
            CacheValidationsReceived = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_VALIDATIONS_CACHE_RECEIVED);

            registrationsIssued                  = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_REGISTRATIONS_ISSUED);
            RegistrationsLocal                   = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_REGISTRATIONS_LOCAL);
            RegistrationsRemoteSent              = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_REGISTRATIONS_REMOTE_SENT);
            RegistrationsRemoteReceived          = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_REGISTRATIONS_REMOTE_RECEIVED);
            registrationsSingleActIssued         = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_REGISTRATIONS_SINGLE_ACT_ISSUED);
            RegistrationsSingleActLocal          = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_REGISTRATIONS_SINGLE_ACT_LOCAL);
            RegistrationsSingleActRemoteSent     = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_REGISTRATIONS_SINGLE_ACT_REMOTE_SENT);
            RegistrationsSingleActRemoteReceived = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_REGISTRATIONS_SINGLE_ACT_REMOTE_RECEIVED);
            unregistrationsIssued                = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_UNREGISTRATIONS_ISSUED);
            UnregistrationsLocal                 = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_UNREGISTRATIONS_LOCAL);
            UnregistrationsRemoteSent            = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_UNREGISTRATIONS_REMOTE_SENT);
            UnregistrationsRemoteReceived        = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_UNREGISTRATIONS_REMOTE_RECEIVED);
            unregistrationsManyIssued            = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_UNREGISTRATIONS_MANY_ISSUED);
            UnregistrationsManyRemoteSent        = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_UNREGISTRATIONS_MANY_REMOTE_SENT);
            UnregistrationsManyRemoteReceived    = CounterStatistic.FindOrCreate(StatisticNames.DIRECTORY_UNREGISTRATIONS_MANY_REMOTE_RECEIVED);

            directoryPartitionCount = IntValueStatistic.FindOrCreate(StatisticNames.DIRECTORY_PARTITION_SIZE, () => DirectoryPartition.Count);
            IntValueStatistic.FindOrCreate(StatisticNames.DIRECTORY_RING_MYPORTION_RINGDISTANCE, () => RingDistanceToSuccessor());
            FloatValueStatistic.FindOrCreate(StatisticNames.DIRECTORY_RING_MYPORTION_RINGPERCENTAGE, () => (((float)RingDistanceToSuccessor()) / ((float)(int.MaxValue * 2L))) * 100);
            FloatValueStatistic.FindOrCreate(StatisticNames.DIRECTORY_RING_MYPORTION_AVERAGERINGPERCENTAGE, () => membershipRingList.Count == 0 ? 0 : ((float)100 / (float)membershipRingList.Count));
            IntValueStatistic.FindOrCreate(StatisticNames.DIRECTORY_RING_RINGSIZE, () => membershipRingList.Count);
            StringValueStatistic.FindOrCreate(StatisticNames.DIRECTORY_RING, () =>
            {
                lock (membershipCache)
                {
                    return(Utils.EnumerableToString(membershipRingList, siloAddressPrint));
                }
            });
            StringValueStatistic.FindOrCreate(StatisticNames.DIRECTORY_RING_PREDECESSORS, () => Utils.EnumerableToString(FindPredecessors(MyAddress, 1), siloAddressPrint));
            StringValueStatistic.FindOrCreate(StatisticNames.DIRECTORY_RING_SUCCESSORS, () => Utils.EnumerableToString(FindSuccessors(MyAddress, 1), siloAddressPrint));
        }
        internal void ProcessSiloAddEvent(SiloAddress addedSilo)
        {
            if (logger.IsVerbose)
            {
                logger.Verbose("Processing silo add event for " + addedSilo);
            }

            // Reset our follower list to take the changes into account
            ResetFollowers();

            // check if this is one of our successors (i.e., if I should hold this silo's copy)
            // (if yes, adjust local and/or copied directory partitions by splitting them between old successors and the new one)
            // NOTE: We need to move part of our local directory to the new silo if it is an immediate successor.
            List <SiloAddress> successors = localDirectory.FindSuccessors(localDirectory.MyAddress, 1);

            if (!successors.Contains(addedSilo))
            {
                return;
            }

            // check if this is an immediate successor
            if (successors[0].Equals(addedSilo))
            {
                // split my local directory and send to my new immediate successor his share
                if (logger.IsVerbose)
                {
                    logger.Verbose("Splitting my partition between me and " + addedSilo);
                }
                GrainDirectoryPartition splitPart = localDirectory.DirectoryPartition.Split(
                    grain =>
                {
                    var s = localDirectory.CalculateTargetSilo(grain);
                    return((s != null) && !localDirectory.MyAddress.Equals(s));
                }, false);
                List <ActivationAddress> splitPartListSingle = splitPart.ToListOfActivations(true);
                List <ActivationAddress> splitPartListMulti  = splitPart.ToListOfActivations(false);

                if (splitPartListSingle.Count > 0)
                {
                    if (logger.IsVerbose)
                    {
                        logger.Verbose("Sending " + splitPartListSingle.Count + " single activation entries to " + addedSilo);
                    }
                    localDirectory.Scheduler.QueueTask(async() =>
                    {
                        await localDirectory.GetDirectoryReference(successors[0]).RegisterManySingleActivation(
                            splitPartListSingle, LocalGrainDirectory.NUM_RETRIES);
                        splitPartListSingle.ForEach(
                            activationAddress =>
                            localDirectory.DirectoryPartition.RemoveGrain(activationAddress.Grain));
                    }, localDirectory.RemGrainDirectory.SchedulingContext).Ignore();
                }

                if (splitPartListMulti.Count > 0)
                {
                    if (logger.IsVerbose)
                    {
                        logger.Verbose("Sending " + splitPartListMulti.Count + " entries to " + addedSilo);
                    }
                    localDirectory.Scheduler.QueueTask(async() =>
                    {
                        await localDirectory.GetDirectoryReference(successors[0]).RegisterMany(splitPartListMulti);
                        splitPartListMulti.ForEach(
                            activationAddress =>
                            localDirectory.DirectoryPartition.RemoveGrain(activationAddress.Grain));
                    }, localDirectory.RemGrainDirectory.SchedulingContext).Ignore();
                }
            }
            else
            {
                // adjust partitions by splitting them accordingly between new and old silos
                SiloAddress predecessorOfNewSilo = localDirectory.FindPredecessors(addedSilo, 1)[0];
                if (!directoryPartitionsMap.ContainsKey(predecessorOfNewSilo))
                {
                    // we should have the partition of the predcessor of our new successor
                    logger.Warn(ErrorCode.DirectoryPartitionPredecessorExpected, "This silo is expected to hold directory partition of " + predecessorOfNewSilo);
                }
                else
                {
                    if (logger.IsVerbose)
                    {
                        logger.Verbose("Splitting partition of " + predecessorOfNewSilo + " and creating a copy for " + addedSilo);
                    }
                    GrainDirectoryPartition splitPart = directoryPartitionsMap[predecessorOfNewSilo].Split(
                        grain =>
                    {
                        // Need to review the 2nd line condition.
                        var s = localDirectory.CalculateTargetSilo(grain);
                        return((s != null) && !predecessorOfNewSilo.Equals(s));
                    }, true);
                    directoryPartitionsMap[addedSilo] = splitPart;
                }
            }

            // remove partition of one of the old successors that we do not need to now
            SiloAddress oldSuccessor = directoryPartitionsMap.FirstOrDefault(pair => !successors.Contains(pair.Key)).Key;

            if (oldSuccessor == null)
            {
                return;
            }

            if (logger.IsVerbose)
            {
                logger.Verbose("Removing copy of the directory partition of silo " + oldSuccessor + " (holding copy of " + addedSilo + " instead)");
            }
            directoryPartitionsMap.Remove(oldSuccessor);
        }
 public ClusterLocalRegistrar(GrainDirectoryPartition directoryPartition)
 {
     this.directoryPartition = directoryPartition;
 }