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);
         }
     }
 }