public async Task ReceiveResultTest()
        {
            var serializeMock = new Mock <BaseSerializer>();

            serializeMock.Setup(serializer => serializer.Deserialize <int>(It.IsAny <ArraySegment <byte> >(), It.IsAny <Session>())).Returns(111);
            serializeMock.Setup(serializer => serializer.Serialize(It.IsAny <A>(), It.IsAny <Session>())).Returns(new byte[10]);
            var executor      = new HostOperationExecutor <DefaultMessage, DefaultMessage>(OperationRuntimeModel.CreateFromAttribute(new[] { typeof(A) }), serializeMock.Object, new Mock <SessionCollection>().Object, new NullLoggerFactory());
            var mockGenerator = new Mock <IGeneratorId>();

            mockGenerator.Setup(id => id.Generate()).Returns(100);
            executor.MessageIdGenerator = mockGenerator.Object;
            IResponseReceiver <DefaultMessage> e = executor;

            Task.Delay(100).ContinueWith(_ => e.Receive(new DefaultMessage()
            {
                OperationCode = 0, Status = BuiltInOperationState.Success, OperationData = new byte[10], Id = 100
            }))
            .GetAwaiter();

            var result = await executor.Execute <A, int>(new A());

            Assert.Equal(111, result.Result);
        }
예제 #2
0
        public async Task DispatchAsync(Session session)
        {
            while (session.HasAvailableData)
            {
                var rawMessage = await session.ReceiveMessageAsync();

                var type = _serializer.ReadMessageType(rawMessage);
                switch (type)
                {
                case TypeMessage.Response:
                    if (_responseReceiver == null)
                    {
                        throw new Exception("Don't subscribed receive event");
                    }
                    _responseReceiver.Receive(_serializer.Deserialize <TResponse>(rawMessage, session));
                    continue;

                case TypeMessage.Request:
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
                var request     = _serializer.Deserialize <TRequest>(rawMessage, session);
                var description = Model.GetDescriptionBy(request.OperationCode);
                var context     = new RequestContext <TRequest>(request, session, description, _descriptionRuntimeModel.GetByOperation(description.OperationType));
                try
                {
                    if (GlobalRequestFilter != null)
                    {
                        var response = await GlobalRequestFilter.Handle(context);

                        response.Id   = request.Id;
                        response.Type = TypeMessage.Response;
                        if (response.Status != BuiltInOperationState.Success)
                        {
                            await session.SendMessageAsync(_serializer.Serialize(response, session).To(), description.ForResponse);

                            continue;
                        }
                    }

                    if (IsContinue(request))
                    {
                        continue;
                    }


                    var rawResponse = await ProcessHandler(request, context, CreateCancellationToken(request, description));

                    if (description.WaitResponse)
                    {
                        await SendAsync(session, rawResponse, request, description.ForResponse);
                    }
                }
                catch (OperationCanceledException e) { Logger.LogInformation("Operation canceled: {request}, {exception}", request, e); }
                catch (Exception e)
                {
                    try
                    {
                        Logger.LogError("Handle error : {exception}", e);
                    }
                    finally
                    {
                        var failOp = new TResponse()
                        {
                            Id            = request.Id,
                            Type          = TypeMessage.Response,
                            OperationCode = request.OperationCode,
                            Status        = BuiltInOperationState.InternalError,
                            OperationData = DebugMode ? _serializer.Serialize(e.Message, session) : null
                        };
                        await session.SendMessageAsync(_serializer.Serialize(failOp, session).To(), MinRequiredDeliveryMode.ReliableWithOrdered);
                    }
                }
                finally
                {
                    RemoveCancellationSource(request);
                }
            }
        }