/// <summary> /// Returns a list of activations (along with the version number of the list) for the given grain. /// If the grain is not found, null is returned. /// </summary> /// <param name="grain"></param> /// <returns></returns> internal AddressesAndTag LookUpActivations(GrainId grain) { var result = new AddressesAndTag(); lock (lockable) { IGrainInfo graininfo; if (partitionData.TryGetValue(grain, out graininfo)) { result.Addresses = new List<ActivationAddress>(); result.VersionTag = partitionData[grain].VersionTag; foreach (var route in partitionData[grain].Instances) { if (IsValidSilo(route.Value.SiloAddress)) result.Addresses.Add(ActivationAddress.GetAddress(route.Value.SiloAddress, grain, route.Key)); } } } return result; }
/// <summary> /// Returns a list of activations (along with the version number of the list) for the given grain. /// If the grain is not found, null is returned. /// </summary> /// <param name="grain"></param> /// <returns></returns> internal AddressesAndTag LookUpActivations(GrainId grain) { var result = new AddressesAndTag(); ActivationId[] activationIds; IActivationInfo[] activationInfos; const int arrayReusingThreshold = 100; int grainInfoInstancesCount; lock (lockable) { IGrainInfo graininfo; if (!partitionData.TryGetValue(grain, out graininfo)) { return result; } result.VersionTag = graininfo.VersionTag; grainInfoInstancesCount = graininfo.Instances.Count; if (grainInfoInstancesCount < arrayReusingThreshold) { if ((activationIds = activationIdsHolder) == null) { activationIdsHolder = activationIds = new ActivationId[arrayReusingThreshold]; } if ((activationInfos = activationInfosHolder) == null) { activationInfosHolder = activationInfos = new IActivationInfo[arrayReusingThreshold]; } } else { activationIds = new ActivationId[grainInfoInstancesCount]; activationInfos = new IActivationInfo[grainInfoInstancesCount]; } graininfo.Instances.Keys.CopyTo(activationIds, 0); graininfo.Instances.Values.CopyTo(activationInfos, 0); } result.Addresses = new List<ActivationAddress>(grainInfoInstancesCount); for (var i = 0; i < grainInfoInstancesCount; i++) { var activationInfo = activationInfos[i]; if (IsValidSilo(activationInfo.SiloAddress)) { result.Addresses.Add(ActivationAddress.GetAddress(activationInfo.SiloAddress, grain, activationIds[i])); } activationInfos[i] = null; activationIds[i] = null; } return result; }
public bool FastLookup(GrainId grain, out AddressesAndTag addresses) { return directory.LocalLookup(grain, out addresses) && addresses.Addresses != null && addresses.Addresses.Count > 0; // NOTE: only check with the local directory cache. // DO NOT check in the local activations TargetDirectory!!! // The only source of truth about which activation should be legit to is the state of the ditributed directory. // Everyone should converge to that (that is the meaning of "eventualy consistency - eventualy we converge to one truth"). // If we keep using the local activation, it may not be registered in th directory any more, but we will never know that and keep using it, // thus volaiting the single-activation semantics and not converging even eventualy! }
/// <summary> /// Returns a list of activations (along with the version number of the list) for the given grain. /// If the grain is not found, null is returned. /// </summary> /// <param name="grain"></param> /// <returns></returns> internal AddressesAndTag LookUpGrain(GrainId grain) { var result = new AddressesAndTag(); lock (lockable) { if (partitionData.ContainsKey(grain)) { result.Addresses = new List<ActivationAddress>(); result.VersionTag = partitionData[grain].VersionTag; foreach (var route in partitionData[grain].Instances.Where(route => IsValidSilo(route.Value.SiloAddress))) { result.Addresses.Add(ActivationAddress.GetAddress(route.Value.SiloAddress, grain, route.Key, route.Value.RegistrationStatus)); } } } return result; }