protected internal static object DeserializeGrainReference(Type t, IDeserializationContext context) { var reader = context.StreamReader; GrainId id = reader.ReadGrainId(); byte siloAddressPresent = reader.ReadByte(); if (siloAddressPresent != 0) { // Unused: silo. // Note, this should become part of the GrainId when reading a legacy SystemTarget grain id, and therefore converting it to a new GrainId _ = reader.ReadSiloAddress(); } bool expectObserverId = id.IsClient(); if (expectObserverId) { _ = GuidId.DeserializeFromStream(reader); } // store as null, serialize as empty. var genericArg = reader.ReadString(); if (string.IsNullOrEmpty(genericArg)) { genericArg = null; } var runtimeClient = context.AdditionalContext as IRuntimeClient; var runtime = runtimeClient?.GrainReferenceRuntime; return(GrainReference.FromGrainId(id, runtime, genericArg)); }
public bool TryLocalLookup(GrainId grainId, out List <ActivationAddress> addresses) { if (grainId.IsClient()) { return(this.inClusterGrainLocator.TryLocalLookup(grainId, out addresses)); } if (this.cache.LookUp(grainId, out var results)) { // IGrainDirectory only supports single activation var result = results[0]; // If the silo is dead, remove the entry if (this.knownDeadSilos.Contains(result.Item1)) { this.cache.Remove(grainId); } else { // Entry found and valid -> return it addresses = new List <ActivationAddress>() { ActivationAddress.GetAddress(result.Item1, grainId, result.Item2) }; return(true); } } addresses = null; return(false); }
private PlacementResult SelectActivationCore(PlacementStrategy strategy, GrainId target, IPlacementRuntime context) { if (target.IsClient()) { throw new InvalidOperationException("Cannot use StatelessWorkerStrategy to route messages to client grains."); } // If there are available (not busy with a request) activations, it returns the first one. // If all are busy and the number of local activations reached or exceeded MaxLocal, it randomly returns one of them. // Otherwise, it requests creation of a new activation. List <ActivationData> local; if (context.LocalSiloStatus.IsTerminating()) { return(null); } if (!context.LocalLookup(target, out local) || local.Count == 0) { return(null); } var placement = (StatelessWorkerPlacement)strategy; foreach (var activation in local) { ActivationData info; if (!context.TryGetActivationData(activation.ActivationId, out info) || info.State != ActivationState.Valid || !info.IsInactive) { continue; } return(PlacementResult.IdentifySelection(ActivationAddress.GetAddress(context.LocalSilo, target, activation.ActivationId))); } if (local.Count >= placement.MaxLocal) { var id = local[local.Count == 1 ? 0 : random.Next(local.Count)].ActivationId; return(PlacementResult.IdentifySelection(ActivationAddress.GetAddress(context.LocalSilo, target, id))); } return(null); }
public async Task <List <ActivationAddress> > Lookup(GrainId grainId) { if (grainId.IsClient()) { return(await this.inClusterGrainLocator.Lookup(grainId)); } List <ActivationAddress> results; // Check cache first if (TryLocalLookup(grainId, out results)) { return(results); } results = new List <ActivationAddress>(); var entry = await this.grainDirectory.Lookup(((LegacyGrainId)grainId).ToParsableString()); // Nothing found if (entry == null) { return(results); } var activationAddress = entry.ToActivationAddress(); // Check if the entry is pointing to a dead silo if (this.knownDeadSilos.Contains(activationAddress.Silo)) { // Remove it from the directory await this.grainDirectory.Unregister(entry); } else { // Add to the local cache and return it results.Add(activationAddress); this.cache.AddOrUpdate(grainId, new List <Tuple <SiloAddress, ActivationId> > { Tuple.Create(activationAddress.Silo, activationAddress.Activation) }, 0); } return(results); }
protected internal static object DeserializeGrainReference(Type t, IDeserializationContext context) { var reader = context.StreamReader; GrainId id = reader.ReadGrainId(); SiloAddress silo = null; GuidId observerId = null; byte siloAddressPresent = reader.ReadByte(); if (siloAddressPresent != 0) { silo = reader.ReadSiloAddress(); } bool expectObserverId = id.IsClient(); if (expectObserverId) { observerId = GuidId.DeserializeFromStream(reader); } // store as null, serialize as empty. var genericArg = reader.ReadString(); if (string.IsNullOrEmpty(genericArg)) { genericArg = null; } var runtimeClient = context.AdditionalContext as IRuntimeClient; var runtime = runtimeClient?.GrainReferenceRuntime; if (expectObserverId) { return(GrainReference.NewObserverGrainReference(id, observerId, runtime)); } return(GrainReference.FromGrainId(id, runtime, genericArg, silo)); }
private IGrainLocator GetGrainLocator(GrainId grainId) { return(!grainId.IsClient() && IsUsingCustomGrainLocator(grainId) ? (IGrainLocator)this.cachedGrainLocator : (IGrainLocator)this.dhtGrainLocator); }