示例#1
0
        ///<summary>
        /// actual response handling including the response handler wrapper for sync or async callback
        ///</summary>
        private async Task ResponseHandlerCallback <T, TResult>(ResponseSocket socket, ResponseHandler <T, TResult> handler, CancellationToken token)
            where T : class, new()
            where TResult : class
        {
            if (!respondingIsActive || token.IsCancellationRequested)
            {
                Dispose();
                _configuration.Logger.Log(new InfoLogMsg("Task was cancelled by cancellationRequest"));
                return;
            }

            try
            {
                Message <TResult> response = null;
                try
                {
                    // block on this thread for incoming requests of the type T (Request)
                    NetMQMessage incomingRequest = socket.ReceiveMultipartMessage();
                    _configuration.Logger.Log(new DebugLogMsg($"handling response for [Request:{typeof(T)}] and [Response:{typeof(TResult)}]"));

                    var     actualRequestResult = incomingRequest.ParseRqRepMessage <T>(_configuration);
                    TResult result = await handler.HandleAsync(actualRequestResult);

                    response = new RequestReplyMessage <TResult>(_configuration, result, actualRequestResult.IsSuccess);
                    _configuration.Logger.Log(new DebugLogMsg($"sending response for [Request:{typeof(T)}] and [Response:{typeof(TResult)}]"));
                }
                catch (System.Exception ex)
                {
                    // failure to parse or any other exception leads to a non successful response, which then in turn can be handled on the request side
                    _configuration.Logger.Log(new ErrorLogMsg($"Responding to [Request:{typeof(T)}] with [Response:{typeof(TResult)}] did fail: " + ex.Message));
                    var msgParts = new [] { ex.GetType().Name, ex.Message, ex.StackTrace };
                    var msg      = Environment.NewLine + string.Join(Environment.NewLine, msgParts);
                    response = RequestReplyMessage <TResult> .FromError(_configuration, msg);
                }

                // try send response with timeout
                bool noTimeout = socket.TrySendMultipartMessage(_configuration.TimeOut, response);
                if (!noTimeout)
                {
                    _configuration.Logger.Log(new ErrorLogMsg($"Responding to [Request:{typeof(T)}] with [Response:{typeof(TResult)}] timed-out after {_configuration.TimeOut}"));
                }
            }
            catch (NetMQ.TerminatingException terminating)
            {
                _configuration.Logger.Log(new ErrorLogMsg($"repsonseHandler failed with terminating exception: [{terminating.Message}]"));
                Dispose();
            }
        }
示例#2
0
        private async Task <XtResult <TResult> > DoRequestAsync <T, TResult>(T request)
            where T : class, new()
            where TResult : class
        {
            const string operation = "request";

            _configuration.Logger.Log(new DebugLogMsg($"Send Request<{typeof(T)}, {typeof(TResult)}> to Address - {_configuration.Address()}"));
            using var rqSocket = new RequestSocket();
            rqSocket.Connect(_configuration.Address());

            var message = new RequestReplyMessage <T>(_configuration, request);

            return(await Task.Run(() =>
            {
                // the request to be send with timeout
                bool rqDidNotTimeOut = rqSocket.TrySendMultipartMessage(_configuration.TimeOut, message);
                if (!rqDidNotTimeOut)
                {
                    return XtResult <TResult> .Failed(new TimeoutException($"Request<{typeof(T)}, {typeof(TResult)}> timed out"), operation);
                }

                _configuration.Logger.Log(new DebugLogMsg($"successfully sent [Request:{typeof(T)}] and waiting for response [Response:{typeof(TResult)}]"));
                // wait for the response with timeout
                var response = new NetMQMessage();
                bool noTimeOut = rqSocket.TryReceiveMultipartMessage(_configuration.TimeOut, ref response, expectedFrameCount: 3);
                if (!noTimeOut)
                {
                    return XtResult <TResult> .Failed(new TimeoutException($"Request<{typeof(T)}, {typeof(TResult)}> timed out"), operation);
                }

                _configuration.Logger.Log(new DebugLogMsg($"received Response [Response:{typeof(TResult)}]"));

                // parse the response and return the result
                var xtResult = response.ParseRqRepMessage <TResult>(_configuration);

                return xtResult.IsSuccess
                        ? XtResult <TResult> .Success(xtResult.GetResult(), operation)
                        : XtResult <TResult> .Failed(xtResult.Exception, operation);
            }));
        }