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); } } }
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); } } }