Task <Message> SendMesageToActorAsync(ActorTargetHeader actorTargetHeader, IOperationContext operation) { var msg = operation.Message; Guid requestId = Guid.NewGuid(); var continuation = new PendingOperation(requestId); if (!PendingOperationsByRequestId.TryAdd(requestId, continuation)) { throw new Exception("RequestId has collided!!!"); } var expiration = Task.Delay(TimeSpan.FromSeconds(_config.SendTimeoutSec), continuation.Expiration.Token); expiration.ContinueWith(_ => { PendingOperation dummy; if (PendingOperationsByRequestId.TryRemove(continuation.RequestId, out dummy)) { continuation.TCS.SetException( new TimeoutException($"SendMesageToActorAsync<{requestId}, {msg}> has Expired after {_config.SendTimeoutSec} s")); } }); msg.AttachHeader(new ActorDirectReplyHeader(new ActorRef(_serverNode.Address, actorTargetHeader.ActorKey))); SendToEventHub(actorTargetHeader, msg, requestId, operation); return(continuation.TCS.Task); }
void SendOneWayMesageToActor(ActorTargetHeader actorTargetHeader, IOperationContext operation) { var msg = operation.Message; Guid requestId = Guid.NewGuid(); SendToEventHub(actorTargetHeader, msg, requestId, operation); }
public Task <IActorProxy> GetActor(ActorKey actorKey) { var header = new ActorTargetHeader(actorKey); return(Task.FromResult <IActorProxy>( new DelegatingActorProxy(new ActorRef(new IPEndPoint(IPAddress.None, 0), actorKey), (context, msg) => SendMesageToActorAsync(header, new OperationContext(context.ReplyChannel, msg, context.ActivityId)), (context, msg) => SendOneWayMesageToActor(header, new OperationContext(context.ReplyChannel, msg, context.ActivityId)), Observable.Never <IActorProxy>()))); }
async void SendToEventHub(ActorTargetHeader actorTargetHeader, Message msg, Guid requestId, IOperationContext operation) { msg.AttachHeader(new OperationHeader(requestId, OperationType.Request, operation.ActivityId)); msg.AttachHeader(actorTargetHeader); using (var stream = new MemoryStream()) { _serializer.Serialize(msg, stream); stream.Position = 0; try { await _eventHubClient.SendAsync(new EventData(stream) { PartitionKey = actorTargetHeader.ActorKey.Id }); } catch (Exception ex) { _logger.FailedToSendMessage(requestId, msg, ex); } } }