public HostedClient( IRuntimeClient runtimeClient, ClientObserverRegistrar clientObserverRegistrar, ILocalSiloDetails siloDetails, ILogger <HostedClient> logger, IGrainReferenceRuntime grainReferenceRuntime, IInternalGrainFactory grainFactory, InvokableObjectManager invokableObjectManager, MessageCenter messageCenter, MessagingTrace messagingTrace) { this.incomingMessages = Channel.CreateUnbounded <Message>(new UnboundedChannelOptions { SingleReader = true, SingleWriter = false, AllowSynchronousContinuations = false, }); this.runtimeClient = runtimeClient; this.clientObserverRegistrar = clientObserverRegistrar; this.grainReferenceRuntime = grainReferenceRuntime; this.grainFactory = grainFactory; this.invokableObjects = invokableObjectManager; this.siloMessageCenter = messageCenter; this.messagingTrace = messagingTrace; this.logger = logger; this.ClientId = ClientGrainId.Create($"hosted-{messageCenter.MyAddress.ToParsableString()}"); this.ClientAddress = ActivationAddress.NewActivationAddress(siloDetails.SiloAddress, this.ClientId.GrainId); }
/// <inheritdoc /> public bool TryDispatchToClient(Message message) { if (!ClientGrainId.TryParse(message.TargetGrain, out var targetClient) || !this.ClientId.Equals(targetClient)) { return(false); } if (message.IsExpired) { this.messagingTrace.OnDropExpiredMessage(message, MessagingStatisticsGroup.Phase.Receive); return(true); } if (message.Direction == Message.Directions.Response) { // Requests are made through the runtime client, so deliver responses to the rutnime client so that the request callback can be executed. this.runtimeClient.ReceiveResponse(message); } else { // Requests agrainst client objects are scheduled for execution on the client. this.incomingMessages.Writer.TryWrite(message); } return(true); }
internal void ClientDropped(ClientGrainId clientId) { var addr = GetClientActivationAddress(clientId); scheduler.QueueTask( () => ExecuteWithRetries(() => grainDirectory.UnregisterAsync(addr, Orleans.GrainDirectory.UnregistrationCause.Force), ErrorCode.ClientRegistrarFailedToUnregister, String.Format("Directory.UnRegisterAsync {0} failed.", addr)), this).Ignore(); }
internal void ClientAdded(ClientGrainId clientId) { // Use a ActivationId that is hashed from clientId, and not random ActivationId. // That way, when we refresh it in the directiry, it's the same one. var addr = GetClientActivationAddress(clientId); scheduler.QueueTask( () => ExecuteWithRetries(() => grainDirectory.RegisterAsync(addr, singleActivation: false), ErrorCode.ClientRegistrarFailedToRegister, String.Format("Directory.RegisterAsync {0} failed.", addr)), this).Ignore(); }
private ActivationAddress GetClientActivationAddress(ClientGrainId clientId) { // Need to pick a unique deterministic ActivationId for this client. // We store it in the grain directory and there for every GrainId we use ActivationId as a key // so every GW needs to behave as a different "activation" with a different ActivationId (its not enough that they have different SiloAddress) string stringToHash = clientId.ToString() + myAddress.Endpoint + myAddress.Generation.ToString(System.Globalization.CultureInfo.InvariantCulture); Guid hash = Utils.CalculateGuidHash(stringToHash); var activationId = ActivationId.GetActivationId(UniqueKey.NewKey(hash)); return(ActivationAddress.GetAddress(myAddress, clientId.GrainId, activationId)); }
/// <summary> /// Returns the <see cref="ClientGrainId"/> associated with this instance. /// </summary> public ClientGrainId GetClientId() { if (!ClientGrainId.TryParse(this.GrainId, out var result)) {