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 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); } } }
private static int CompareSiloAddressesForRing(SiloAddress left, SiloAddress right) { var leftHash = left.GetConsistentHashCode(); var rightHash = right.GetConsistentHashCode(); return(leftHash.CompareTo(rightHash)); }
internal SiloAddress CalculateGrainDirectoryPartition(GrainId grainId) { // give a special treatment for special grains if (grainId.IsSystemTarget) { if (log.IsEnabled(LogLevel.Trace)) { log.LogTrace( "Silo {LocalSilo} looked for a system target {SystemTarget}, returned {ResultSilo}", this.siloAddress, grainId, this.siloAddress); } // every silo owns its system targets return(this.siloAddress); } if (this.ring.Count == 0) { return(null); } SiloAddress siloAddress = null; int hash = unchecked ((int)grainId.GetUniformHashCode()); // need to implement a binary search, but for now simply traverse the list of silos sorted by their hashes for (var index = this.ring.Count - 1; index >= 0; --index) { var item = this.ring[index]; if (item.GetConsistentHashCode() <= hash) { siloAddress = item; break; } } if (siloAddress == null) { // If not found in the traversal, last silo will do (we are on a ring). // We checked above to make sure that the list isn't empty, so this should always be safe. siloAddress = this.ring[this.ring.Count - 1]; } if (log.IsEnabled(LogLevel.Trace)) { log.LogTrace( "Silo {LocalSilo} calculated directory partition owner silo {Silo} for grain {Grain}: {GrainHash} --> {SiloHash}", this.siloAddress, siloAddress, grainId, hash, siloAddress?.GetConsistentHashCode()); } return(siloAddress); }
public ConsistentRingProvider(SiloAddress siloAddr) { log = TraceLogger.GetLogger(typeof(ConsistentRingProvider).Name); membershipRingList = new List <SiloAddress>(); MyAddress = siloAddr; myKey = MyAddress.GetConsistentHashCode(); // add myself to the list of members AddServer(MyAddress); MyRange = RangeFactory.CreateFullRange(); // i am responsible for the whole range statusListeners = new List <IRingRangeListener>(); Start(); }
public ConsistentRingProvider(SiloAddress siloAddr) { log = LogManager.GetLogger(typeof(ConsistentRingProvider).Name); membershipRingList = new List<SiloAddress>(); MyAddress = siloAddr; myKey = MyAddress.GetConsistentHashCode(); // add myself to the list of members AddServer(MyAddress); MyRange = RangeFactory.CreateFullRange(); // i am responsible for the whole range statusListeners = new List<IRingRangeListener>(); Start(); }
internal void AddServer(SiloAddress silo) { lock (membershipRingList) { if (membershipRingList.Contains(silo)) { return; // we already have this silo } int myOldIndex = membershipRingList.FindIndex(elem => elem.Equals(MyAddress)); if (!(membershipRingList.Count == 0 || myOldIndex != -1)) { throw new OrleansException(string.Format("{0}: Couldn't find my position in the ring {1}.", MyAddress, Utils.EnumerableToString(membershipRingList))); } // insert new silo in the sorted order int 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); // relating to triggering handler ... new node took over some of my responsibility if (index == myOldIndex || // new node was inserted in my place (myOldIndex == 0 && index == membershipRingList.Count - 1)) // I am the first node, and the new server is the last node { IRingRange oldRange = MyRange; try { MyRange = RangeFactory.CreateRange(unchecked ((uint)hash), unchecked ((uint)myKey)); } catch (OverflowException exc) { log.Error(ErrorCode.ConsistentRingProviderBase + 5, String.Format("OverflowException: hash as int= x{0, 8:X8}, hash as uint= x{1, 8:X8}, myKey as int x{2, 8:X8}, myKey as uint x{3, 8:X8}.", hash, (uint)hash, myKey, (uint)myKey), exc); } NotifyLocalRangeSubscribers(oldRange, MyRange, false); } log.Info("Added Server {0}. Current view: {1}", silo.ToStringWithHashCode(), this.ToString()); } }
private static long CalcRingDistance(SiloAddress silo1, SiloAddress silo2) { const long ringSize = int.MaxValue * 2L; long hash1 = silo1.GetConsistentHashCode(); long hash2 = silo2.GetConsistentHashCode(); if (hash2 > hash1) { return(hash2 - hash1); } if (hash2 < hash1) { return(ringSize - (hash1 - hash2)); } return(0); }
internal void RemoveServer(SiloAddress silo) { lock (membershipRingList) { int indexOfFailedSilo = membershipRingList.FindIndex(elem => elem.Equals(silo)); if (indexOfFailedSilo < 0) { return; // we have already removed this silo } membershipRingList.Remove(silo); // related to triggering handler int myNewIndex = membershipRingList.FindIndex(elem => elem.Equals(MyAddress)); if (myNewIndex == -1) { throw new OrleansException(string.Format("{0}: Couldn't find my position in the ring {1}.", MyAddress, this.ToString())); } bool wasMyPred = ((myNewIndex == indexOfFailedSilo) || (myNewIndex == 0 && indexOfFailedSilo == membershipRingList.Count)); // no need for '- 1' if (wasMyPred) // failed node was our predecessor { if (log.IsVerbose) { log.Verbose("Failed server was my pred? {0}, updated view {1}", wasMyPred, this.ToString()); } IRingRange oldRange = MyRange; if (membershipRingList.Count == 1) // i'm the only one left { MyRange = RangeFactory.CreateFullRange(); NotifyLocalRangeSubscribers(oldRange, MyRange, true); } else { int myNewPredIndex = myNewIndex == 0 ? membershipRingList.Count - 1 : myNewIndex - 1; int myPredecessorsHash = membershipRingList[myNewPredIndex].GetConsistentHashCode(); MyRange = RangeFactory.CreateRange(unchecked ((uint)myPredecessorsHash), unchecked ((uint)myKey)); NotifyLocalRangeSubscribers(oldRange, MyRange, true); } } log.Info("Removed Server {0} hash {1}. Current view {2}", silo, silo.GetConsistentHashCode(), this.ToString()); } }
/// <summary> /// Compare SiloAddress-es based on their consistent hash code /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> private static int CompareSiloAddressesByHash(SiloAddress x, SiloAddress y) { if (x == null) { return(y == null ? 0 : -1); } else { if (y == null) { return(1); } else { // real comparison is here return(x.GetConsistentHashCode().CompareTo(y.GetConsistentHashCode())); } } }
public override string ToString() { lock (membershipRingList) { if (membershipRingList.Count == 1) { return(Utils.EnumerableToString(membershipRingList, silo => String.Format("{0} -> {1}", silo.ToStringWithHashCode(), RangeFactory.CreateFullRange()))); } var sb = new StringBuilder("["); for (int i = 0; i < membershipRingList.Count; i++) { SiloAddress curr = membershipRingList[i]; SiloAddress next = membershipRingList[(i + 1) % membershipRingList.Count]; IRingRange range = RangeFactory.CreateRange(unchecked ((uint)curr.GetConsistentHashCode()), unchecked ((uint)next.GetConsistentHashCode())); sb.Append(String.Format("{0} -> {1}, ", curr.ToStringWithHashCode(), range)); } sb.Append("]"); return(sb.ToString()); } }
private bool IsSiloNextInTheRing(SiloAddress siloAddr, uint hash, bool excludeMySelf) { return siloAddr.GetConsistentHashCode() >= hash && (!siloAddr.Equals(MyAddress) || !excludeMySelf); }
/// <summary> /// Finds the silo that owns the given hash value. /// This routine will always return a non-null silo address unless the excludeThisSiloIfStopping parameter is true, /// this is the only silo known, and this silo is stopping. /// </summary> /// <param name="hash"></param> /// <param name="excludeThisSiloIfStopping"></param> /// <returns></returns> public SiloAddress CalculateTargetSilo(uint hash, bool excludeThisSiloIfStopping = true) { SiloAddress siloAddress = null; lock (membershipRingList) { // excludeMySelf from being a TargetSilo if we're not running and the excludeThisSIloIfStopping flag is true. see the comment in the Stop method. bool excludeMySelf = excludeThisSiloIfStopping && !isRunning; if (membershipRingList.Count == 0) { // If the membership ring is empty, then we're the owner by default unless we're stopping. return(excludeMySelf ? null : MyAddress); } // use clockwise ... current code in membershipOracle.CalculateTargetSilo() does counter-clockwise ... // if you want to stick to counter-clockwise, change the responsibility definition in 'In()' method & responsibility defs in OrleansReminderMemory // need to implement a binary search, but for now simply traverse the list of silos sorted by their hashes for (int index = 0; index < membershipRingList.Count; ++index) { var siloAddr = membershipRingList[index]; if (IsSiloNextInTheRing(siloAddr, hash, excludeMySelf)) { siloAddress = siloAddr; break; } } if (siloAddress == null) { // if not found in traversal, then first silo should be returned (we are on a ring) // if you go back to their counter-clockwise policy, then change the 'In()' method in OrleansReminderMemory siloAddress = membershipRingList[0]; // vs [membershipRingList.Count - 1]; for counter-clockwise policy // Make sure it's not us... if (siloAddress.Equals(MyAddress) && excludeMySelf) { // vs [membershipRingList.Count - 2]; for counter-clockwise policy siloAddress = membershipRingList.Count > 1 ? membershipRingList[1] : null; } } } if (log.IsVerbose2) { log.Verbose2("Silo {0} calculated ring partition owner silo {1} for key {2}: {3} --> {4}", MyAddress, siloAddress, hash, hash, siloAddress.GetConsistentHashCode()); } return(siloAddress); }
internal void AddServer(SiloAddress silo) { lock (membershipRingList) { if (membershipRingList.Contains(silo)) return; // we already have this silo int myOldIndex = membershipRingList.FindIndex(elem => elem.Equals(MyAddress)); if (!(membershipRingList.Count == 0 || myOldIndex != -1)) throw new OrleansException(string.Format("{0}: Couldn't find my position in the ring {1}.", MyAddress, Utils.EnumerableToString(membershipRingList))); // insert new silo in the sorted order int 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); // relating to triggering handler ... new node took over some of my responsibility if (index == myOldIndex || // new node was inserted in my place (myOldIndex == 0 && index == membershipRingList.Count - 1)) // I am the first node, and the new server is the last node { IRingRange oldRange = MyRange; try { MyRange = RangeFactory.CreateRange(unchecked((uint)hash), unchecked((uint)myKey)); } catch (OverflowException exc) { log.Error(ErrorCode.ConsistentRingProviderBase + 5, String.Format("OverflowException: hash as int= x{0, 8:X8}, hash as uint= x{1, 8:X8}, myKey as int x{2, 8:X8}, myKey as uint x{3, 8:X8}.", hash, (uint)hash, myKey, (uint)myKey), exc); } NotifyLocalRangeSubscribers(oldRange, MyRange, false); } log.Info("Added Server {0}. Current view: {1}", silo.ToStringWithHashCode(), this.ToString()); } }
public async Task <List <ActivationAddress> > FullLookup(GrainId grain) { fullLookups.Increment(); SiloAddress silo = CalculateTargetSilo(grain, false); // No need to check that silo != null since we're passing excludeThisSiloIfStopping = false if (log.IsVerbose) { log.Verbose("Silo {0} fully lookups for {1}-->{2} ({3}-->{4})", MyAddress, grain, silo, grain.GetUniformHashCode(), silo.GetConsistentHashCode()); } // We assyme that getting here means the grain was not found locally (i.e., in TryFullLookup()). // We still check if we own the grain locally to avoid races between the time TryFullLookup() and FullLookup() were called. if (silo.Equals(MyAddress)) { LocalDirectoryLookups.Increment(); var localResult = DirectoryPartition.LookUpGrain(grain); if (localResult == null) { // it can happen that we cannot find the grain in our partition if there were // some recent changes in the membership if (log.IsVerbose2) { log.Verbose2("FullLookup mine {0}=none", grain); } return(new List <ActivationAddress>()); } var a = localResult.Item1.Select(t => ActivationAddress.GetAddress(t.Item1, grain, t.Item2)).Where(addr => IsValidSilo(addr.Silo)).ToList(); if (log.IsVerbose2) { log.Verbose2("FullLookup mine {0}={1}", grain, a.ToStrings()); } LocalDirectorySuccesses.Increment(); return(a); } // Just a optimization. Why sending a message to someone we know is not valid. if (!IsValidSilo(silo)) { throw new OrleansException(String.Format("Current directory at {0} is not stable to perform the lookup for grain {1} (it maps to {2}, which is not a valid silo). Retry later.", MyAddress, grain, silo)); } RemoteLookupsSent.Increment(); Tuple <List <Tuple <SiloAddress, ActivationId> >, int> result = await GetDirectoryReference(silo).LookUp(grain, NUM_RETRIES); // update the cache List <Tuple <SiloAddress, ActivationId> > entries = result.Item1.Where(t => IsValidSilo(t.Item1)).ToList(); List <ActivationAddress> addresses = entries.Select(t => ActivationAddress.GetAddress(t.Item1, grain, t.Item2)).ToList(); if (log.IsVerbose2) { log.Verbose2("FullLookup remote {0}={1}", grain, addresses.ToStrings()); } if (entries.Count > 0) { DirectoryCache.AddOrUpdate(grain, entries, result.Item2); } return(addresses); }
public Task DeleteGrain(GrainId grain) { SiloAddress silo = CalculateTargetSilo(grain); if (silo == null) { // We don't know about any other silos, and we're stopping, so throw throw new InvalidOperationException("Grain directory is stopping"); } if (log.IsVerbose) { log.Verbose("Silo {0} tries to lookup for {1}-->{2} ({3}-->{4})", MyAddress, grain, silo, grain.GetUniformHashCode(), silo.GetConsistentHashCode()); } if (silo.Equals(MyAddress)) { // remove from our partition DirectoryPartition.RemoveGrain(grain); return(TaskDone.Done); } // remove from the cache DirectoryCache.Remove(grain); // send request to the owner return(GetDirectoryReference(silo).DeleteGrain(grain, NUM_RETRIES)); }
private Task UnregisterAsyncImpl(ActivationAddress addr, bool force) { unregistrationsIssued.Increment(); SiloAddress owner = CalculateTargetSilo(addr.Grain); if (owner == null) { // We don't know about any other silos, and we're stopping, so throw throw new InvalidOperationException("Grain directory is stopping"); } if (log.IsVerbose) { log.Verbose("Silo {0} is going to unregister grain {1}-->{2} ({3}-->{4})", MyAddress, addr.Grain, owner, addr.Grain.GetUniformHashCode(), owner.GetConsistentHashCode()); } InvalidateCacheEntry(addr); if (owner.Equals(MyAddress)) { UnregistrationsLocal.Increment(); // if I am the owner, remove the old activation locally DirectoryPartition.RemoveActivation(addr.Grain, addr.Activation, force); return(TaskDone.Done); } UnregistrationsRemoteSent.Increment(); // otherwise, notify the owner return(GetDirectoryReference(owner).Unregister(addr, force, NUM_RETRIES)); }
public bool LocalLookup(GrainId grain, out List <ActivationAddress> addresses) { localLookups.Increment(); SiloAddress silo = CalculateTargetSilo(grain, false); // No need to check that silo != null since we're passing excludeThisSiloIfStopping = false if (log.IsVerbose) { log.Verbose("Silo {0} tries to lookup for {1}-->{2} ({3}-->{4})", MyAddress, grain, silo, grain.GetUniformHashCode(), silo.GetConsistentHashCode()); } // check if we own the grain if (silo.Equals(MyAddress)) { LocalDirectoryLookups.Increment(); addresses = GetLocalDirectoryData(grain); if (addresses == null) { // it can happen that we cannot find the grain in our partition if there were // some recent changes in the membership if (log.IsVerbose2) { log.Verbose2("LocalLookup mine {0}=null", grain); } return(false); } if (log.IsVerbose2) { log.Verbose2("LocalLookup mine {0}={1}", grain, addresses.ToStrings()); } LocalDirectorySuccesses.Increment(); localSuccesses.Increment(); return(true); } // handle cache cacheLookups.Increment(); addresses = GetLocalCacheData(grain); if (addresses == null) { if (log.IsVerbose2) { log.Verbose2("TryFullLookup else {0}=null", grain); } return(false); } if (log.IsVerbose2) { log.Verbose2("LocalLookup cache {0}={1}", grain, addresses.ToStrings()); } cacheSuccesses.Increment(); localSuccesses.Increment(); return(true); }
internal void RemoveServer(SiloAddress silo) { lock (membershipRingList) { int indexOfFailedSilo = membershipRingList.FindIndex(elem => elem.Equals(silo)); if (indexOfFailedSilo < 0) return; // we have already removed this silo membershipRingList.Remove(silo); // related to triggering handler int myNewIndex = membershipRingList.FindIndex(elem => elem.Equals(MyAddress)); if (myNewIndex == -1) throw new OrleansException(string.Format("{0}: Couldn't find my position in the ring {1}.", MyAddress, this.ToString())); bool wasMyPred = ((myNewIndex == indexOfFailedSilo) || (myNewIndex == 0 && indexOfFailedSilo == membershipRingList.Count)); // no need for '- 1' if (wasMyPred) // failed node was our predecessor { if (log.IsVerbose) log.Verbose("Failed server was my pred? {0}, updated view {1}", wasMyPred, this.ToString()); IRingRange oldRange = MyRange; if (membershipRingList.Count == 1) // i'm the only one left { MyRange = RangeFactory.CreateFullRange(); NotifyLocalRangeSubscribers(oldRange, MyRange, true); } else { int myNewPredIndex = myNewIndex == 0 ? membershipRingList.Count - 1 : myNewIndex - 1; int myPredecessorsHash = membershipRingList[myNewPredIndex].GetConsistentHashCode(); MyRange = RangeFactory.CreateRange(unchecked((uint)myPredecessorsHash), unchecked((uint)myKey)); NotifyLocalRangeSubscribers(oldRange, MyRange, true); } } log.Info("Removed Server {0} hash {1}. Current view {2}", silo, silo.GetConsistentHashCode(), this.ToString()); } }
private bool IsSiloNextInTheRing(SiloAddress siloAddr, uint hash, bool excludeMySelf) { return(siloAddr.GetConsistentHashCode() >= hash && (!siloAddr.Equals(MyAddress) || !excludeMySelf)); }
/// <summary> /// Compare SiloAddress-es based on their consistent hash code /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> private static int CompareSiloAddressesByHash(SiloAddress x, SiloAddress y) { if (x == null) { return y == null ? 0 : -1; } else { if (y == null) { return 1; } else { // real comparison is here return x.GetConsistentHashCode().CompareTo(y.GetConsistentHashCode()); } } }
/// <summary> /// Finds the silo that owns the directory information for the given grain ID. /// This method will only be null when I'm the only silo in the cluster and I'm shutting down /// </summary> /// <param name="grainId"></param> /// <returns></returns> public SiloAddress CalculateGrainDirectoryPartition(GrainId grainId) { // give a special treatment for special grains if (grainId.IsSystemTarget()) { if (Constants.SystemMembershipTableType.Equals(grainId)) { if (Seed == null) { var errorMsg = $"Development clustering cannot run without a primary silo. " + $"Please configure {nameof(DevelopmentClusterMembershipOptions)}.{nameof(DevelopmentClusterMembershipOptions.PrimarySiloEndpoint)} " + "or provide a primary silo address to the UseDevelopmentClustering extension. " + "Alternatively, you may want to use reliable membership, such as Azure Table."; throw new ArgumentException(errorMsg, "grainId = " + grainId); } } if (log.IsEnabled(LogLevel.Trace)) { log.Trace("Silo {0} looked for a system target {1}, returned {2}", MyAddress, grainId, MyAddress); } // every silo owns its system targets return(MyAddress); } SiloAddress siloAddress = null; int hash = unchecked ((int)grainId.GetUniformHashCode()); // excludeMySelf from being a TargetSilo if we're not running and the excludeThisSIloIfStopping flag is true. see the comment in the Stop method. // excludeThisSIloIfStopping flag was removed because we believe that flag complicates things unnecessarily. We can add it back if it turns out that flag // is doing something valuable. bool excludeMySelf = !Running; var existing = this.directoryMembership; if (existing.MembershipRingList.Count == 0) { // If the membership ring is empty, then we're the owner by default unless we're stopping. return(!Running ? null : MyAddress); } // need to implement a binary search, but for now simply traverse the list of silos sorted by their hashes for (var index = existing.MembershipRingList.Count - 1; index >= 0; --index) { var item = existing.MembershipRingList[index]; if (IsSiloNextInTheRing(item, hash, excludeMySelf)) { siloAddress = item; break; } } if (siloAddress == null) { // If not found in the traversal, last silo will do (we are on a ring). // We checked above to make sure that the list isn't empty, so this should always be safe. siloAddress = existing.MembershipRingList[existing.MembershipRingList.Count - 1]; // Make sure it's not us... if (siloAddress.Equals(MyAddress) && excludeMySelf) { siloAddress = existing.MembershipRingList.Count > 1 ? existing.MembershipRingList[existing.MembershipRingList.Count - 2] : null; } } if (log.IsEnabled(LogLevel.Trace)) { log.Trace("Silo {0} calculated directory partition owner silo {1} for grain {2}: {3} --> {4}", MyAddress, siloAddress, grainId, hash, siloAddress?.GetConsistentHashCode()); } return(siloAddress); }
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); } }
private static long CalcRingDistance(SiloAddress silo1, SiloAddress silo2) { const long ringSize = int.MaxValue * 2L; long hash1 = silo1.GetConsistentHashCode(); long hash2 = silo2.GetConsistentHashCode(); if (hash2 > hash1) return hash2 - hash1; if (hash2 < hash1) return ringSize - (hash1 - hash2); return 0; }
public bool LocalLookup(GrainId grain, out AddressAndTag result) { localLookups.Increment(); SiloAddress silo = CalculateGrainDirectoryPartition(grain); if (log.IsEnabled(LogLevel.Debug)) { log.Debug("Silo {0} tries to lookup for {1}-->{2} ({3}-->{4})", MyAddress, grain, silo, grain.GetUniformHashCode(), silo?.GetConsistentHashCode()); } //this will only happen if I'm the only silo in the cluster and I'm shutting down if (silo == null) { if (log.IsEnabled(LogLevel.Trace)) { log.Trace("LocalLookup mine {0}=null", grain); } result = new AddressAndTag(); return(false); } // handle cache cacheLookups.Increment(); var address = GetLocalCacheData(grain); if (address != default) { result = new AddressAndTag { Address = address, }; if (log.IsEnabled(LogLevel.Trace)) { log.Trace("LocalLookup cache {0}={1}", grain, result.Address); } cacheSuccesses.Increment(); localSuccesses.Increment(); return(true); } // check if we own the grain if (silo.Equals(MyAddress)) { LocalDirectoryLookups.Increment(); result = GetLocalDirectoryData(grain); if (result.Address == null) { // it can happen that we cannot find the grain in our partition if there were // some recent changes in the membership if (log.IsEnabled(LogLevel.Trace)) { log.Trace("LocalLookup mine {0}=null", grain); } return(false); } if (log.IsEnabled(LogLevel.Trace)) { log.Trace("LocalLookup mine {0}={1}", grain, result.Address); } LocalDirectorySuccesses.Increment(); localSuccesses.Increment(); return(true); } if (log.IsEnabled(LogLevel.Trace)) { log.Trace("TryFullLookup else {0}=null", grain); } result = default; return(false); }