internal async Task <Tuple <string, byte[]> > DispatchWithRemotingAsync(ActorId actorId, string actorMethodName, string daprActorheader, Stream data, CancellationToken cancellationToken) { var actorMethodContext = ActorMethodContext.CreateForActor(actorMethodName); // Get the serialized header var actorMessageHeader = this.serializersManager.GetHeaderSerializer() .DeserializeRequestHeaders(new MemoryStream(Encoding.ASCII.GetBytes(daprActorheader))); var interfaceId = actorMessageHeader.InterfaceId; // Get the deserialized Body. var msgBodySerializer = this.serializersManager.GetRequestMessageBodySerializer(actorMessageHeader.InterfaceId); IActorRequestMessageBody actorMessageBody; using (var stream = new MemoryStream()) { await data.CopyToAsync(stream); actorMessageBody = msgBodySerializer.Deserialize(stream); } // Call the method on the method dispatcher using the Func below. var methodDispatcher = this.methodDispatcherMap.GetDispatcher(actorMessageHeader.InterfaceId, actorMessageHeader.MethodId); // Create a Func to be invoked by common method. async Task <Tuple <string, byte[]> > RequestFunc(Actor actor, CancellationToken ct) { IActorResponseMessageBody responseMsgBody = null; try { responseMsgBody = (IActorResponseMessageBody)await methodDispatcher.DispatchAsync( actor, actorMessageHeader.MethodId, actorMessageBody, this.messageBodyFactory, ct); return(this.CreateResponseMessage(responseMsgBody, interfaceId)); } catch (Exception exception) { // return exception response message return(this.CreateExceptionResponseMessage(exception)); } } return(await this.DispatchInternalAsync(actorId, actorMethodContext, RequestFunc, cancellationToken)); }
internal async Task DispatchWithoutRemotingAsync(ActorId actorId, string actorMethodName, Stream requestBodyStream, Stream responseBodyStream, CancellationToken cancellationToken) { var actorMethodContext = ActorMethodContext.CreateForActor(actorMethodName); // Create a Func to be invoked by common method. var methodInfo = this.actorMethodInfoMap.LookupActorMethodInfo(actorMethodName); async Task <object> RequestFunc(Actor actor, CancellationToken ct) { var parameters = methodInfo.GetParameters(); dynamic awaitable; if (parameters.Length == 0) { awaitable = methodInfo.Invoke(actor, null); } else { // deserialize using stream. var type = parameters[0].ParameterType; var deserializedType = default(object); using (var streamReader = new StreamReader(requestBodyStream)) { var json = await streamReader.ReadToEndAsync(); deserializedType = JsonConvert.DeserializeObject(json, type); } awaitable = methodInfo.Invoke(actor, new object[] { deserializedType }); } await awaitable; // Write Response back if method's return type is other than Task. // Serialize result if it has result (return type was not just Task.) if (methodInfo.ReturnType.Name != typeof(Task).Name) { // already await, Getting result will be non blocking. var x = awaitable.GetAwaiter().GetResult(); return(x); } else { return(default);
internal async Task DispatchWithoutRemotingAsync(ActorId actorId, string actorMethodName, Stream requestBodyStream, Stream responseBodyStream, CancellationToken cancellationToken) { var actorMethodContext = ActorMethodContext.CreateForActor(actorMethodName); // Create a Func to be invoked by common method. var methodInfo = this.actorMethodInfoMap.LookupActorMethodInfo(actorMethodName); async Task <object> RequestFunc(Actor actor, CancellationToken ct) { var parameters = methodInfo.GetParameters(); dynamic awaitable; if (parameters.Length == 0) { awaitable = methodInfo.Invoke(actor, null); } else if (parameters.Length == 1) { // deserialize using stream. var type = parameters[0].ParameterType; var deserializedType = await JsonSerializer.DeserializeAsync(requestBodyStream, type); awaitable = methodInfo.Invoke(actor, new object[] { deserializedType }); } else { var errorMsg = $"Method {string.Concat(methodInfo.DeclaringType.Name, ".", methodInfo.Name)} has more than one parameter and can't be invoked through http"; ActorTrace.Instance.WriteError(TraceType, errorMsg); throw new ArgumentException(errorMsg); } await awaitable; // Handle the return type of method correctly. if (methodInfo.ReturnType.Name != typeof(Task).Name) { // already await, Getting result will be non blocking. var x = awaitable.GetAwaiter().GetResult(); return(x); } else { return(default);
internal async Task DispatchWithoutRemotingAsync(ActorId actorId, string actorMethodName, Stream requestBodyStream, Stream responseBodyStream, CancellationToken cancellationToken) { var actorMethodContext = ActorMethodContext.CreateForActor(actorMethodName); // Create a Func to be invoked by common method. var methodInfo = this.actorMethodInfoMap.LookupActorMethodInfo(actorMethodName); async Task <object> RequestFunc(Actor actor, CancellationToken ct) { var parameters = methodInfo.GetParameters(); dynamic awaitable; if (parameters.Length == 0) { awaitable = methodInfo.Invoke(actor, null); } else { // deserialize using stream. var type = parameters[0].ParameterType; var deserializedType = await JsonSerializer.DeserializeAsync(requestBodyStream, type); awaitable = methodInfo.Invoke(actor, new object[] { deserializedType }); } await awaitable; // Handle the return type of method correctly. if (methodInfo.ReturnType.Name != typeof(Task).Name) { // already await, Getting result will be non blocking. var x = awaitable.GetAwaiter().GetResult(); return(x); } else { return(default);