コード例 #1
0
        protected void AddServer(SiloAddress silo)
        {
            lock (membershipCache)
            {
                if (membershipCache.Contains(silo))
                {
                    // we have already cached this silo
                    return;
                }

                membershipCache.Add(silo);

                // insert new silo in the sorted order
                long hash = silo.GetConsistentHashCode();

                // Find the last silo with hash smaller than the new silo, and insert the latter after (this is why we have +1 here) the former.
                // Notice that FindLastIndex might return -1 if this should be the first silo in the list, but then
                // 'index' will get 0, as needed.
                int index = membershipRingList.FindLastIndex(siloAddr => siloAddr.GetConsistentHashCode() < hash) + 1;
                membershipRingList.Insert(index, silo);

                HandoffManager.ProcessSiloAddEvent(silo);

                if (log.IsVerbose)
                {
                    log.Verbose("Silo {0} added silo {1}", MyAddress, silo);
                }
            }
        }
コード例 #2
0
        protected void AddServer(SiloAddress silo)
        {
            lock (this.writeLock)
            {
                var existing = this.directoryMembership;
                if (existing.MembershipCache.Contains(silo))
                {
                    // we have already cached this silo
                    return;
                }

                // insert new silo in the sorted order
                long hash = silo.GetConsistentHashCode();

                // Find the last silo with hash smaller than the new silo, and insert the latter after (this is why we have +1 here) the former.
                // Notice that FindLastIndex might return -1 if this should be the first silo in the list, but then
                // 'index' will get 0, as needed.
                int index = existing.MembershipRingList.FindLastIndex(siloAddr => siloAddr.GetConsistentHashCode() < hash) + 1;

                this.directoryMembership = new DirectoryMembership(
                    existing.MembershipRingList.Insert(index, silo),
                    existing.MembershipCache.Add(silo));

                HandoffManager.ProcessSiloAddEvent(silo);

                AdjustLocalDirectory(silo, dead: false);
                AdjustLocalCache(silo, dead: false);

                if (log.IsEnabled(LogLevel.Debug))
                {
                    log.Debug("Silo {0} added silo {1}", MyAddress, silo);
                }
            }
        }
コード例 #3
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);
        }
コード例 #4
0
        // Note that this implementation stops processing directory change requests (Register, Unregister, etc.) when the Stop event is raised.
        // This means that there may be a short period during which no silo believes that it is the owner of directory information for a set of
        // grains (for update purposes), which could cause application requests that require a new activation to be created to time out.
        // The alternative would be to allow the silo to process requests after it has handed off its partition, in which case those changes
        // would receive successful responses but would not be reflected in the eventual state of the directory.
        // It's easy to change this, if we think the trade-off is better the other way.
        public void Stop(bool doOnStopHandoff)
        {
            // This will cause remote write requests to be forwarded to the silo that will become the new owner.
            // Requests might bounce back and forth for a while as membership stabilizes, but they will either be served by the
            // new owner of the grain, or will wind up failing. In either case, we avoid requests succeeding at this silo after we've
            // begun stopping, which could cause them to not get handed off to the new owner.
            Running = false;

            if (doOnStopHandoff)
            {
                HandoffManager.ProcessSiloStoppingEvent();
            }
            else
            {
                MarkStopPreparationCompleted();
            }
            if (maintainer != null)
            {
                maintainer.Stop();
            }
            DirectoryCache.Clear();
        }
コード例 #5
0
        protected void RemoveServer(SiloAddress silo, SiloStatus status)
        {
            lock (membershipCache)
            {
                if (!membershipCache.Contains(silo))
                {
                    // we have already removed this silo
                    return;
                }

                if (CatalogSiloStatusListener != null)
                {
                    try
                    {
                        // only call SiloStatusChangeNotification once on the catalog and the order is important: call BEFORE updating membershipRingList.
                        CatalogSiloStatusListener.SiloStatusChangeNotification(silo, status);
                    }
                    catch (Exception exc)
                    {
                        log.Error(ErrorCode.Directory_SiloStatusChangeNotification_Exception,
                                  String.Format("CatalogSiloStatusListener.SiloStatusChangeNotification has thrown an exception when notified about removed silo {0}.", silo.ToStringWithHashCode()), exc);
                    }
                }

                // the call order is important
                HandoffManager.ProcessSiloRemoveEvent(silo);
                membershipCache.Remove(silo);
                membershipRingList.Remove(silo);

                AdjustLocalDirectory(silo);
                AdjustLocalCache(silo);

                if (log.IsVerbose)
                {
                    log.Verbose("Silo {0} removed silo {1}", MyAddress, silo);
                }
            }
        }
コード例 #6
0
        protected void RemoveServer(SiloAddress silo, SiloStatus status)
        {
            lock (this.writeLock)
            {
                try
                {
                    // Only notify the catalog once. Order is important: call BEFORE updating membershipRingList.
                    this.catalogOnSiloRemoved?.Invoke(silo, status);
                }
                catch (Exception exc)
                {
                    log.Error(ErrorCode.Directory_SiloStatusChangeNotification_Exception,
                              String.Format("CatalogSiloStatusListener.SiloStatusChangeNotification has thrown an exception when notified about removed silo {0}.", silo.ToStringWithHashCode()), exc);
                }

                var existing = this.directoryMembership;
                if (!existing.MembershipCache.Contains(silo))
                {
                    // we have already removed this silo
                    return;
                }

                // the call order is important
                HandoffManager.ProcessSiloRemoveEvent(silo);

                this.directoryMembership = new DirectoryMembership(
                    existing.MembershipRingList.Remove(silo),
                    existing.MembershipCache.Remove(silo));

                AdjustLocalDirectory(silo, dead: true);
                AdjustLocalCache(silo, dead: true);

                if (log.IsEnabled(LogLevel.Debug))
                {
                    log.Debug("Silo {0} removed silo {1}", MyAddress, silo);
                }
            }
        }