void DispatchEvent(EpoxyHeaders headers, EpoxyProtocol.MessageData messageData, ArraySegment <byte> layerData) { if (messageData.IsError) { logger.Site().Error( "{0} Received event with an error message. Only payload messages are allowed. Conversation ID: {1}", this, headers.conversation_id); return; } Task.Run( async() => { IMessage request = Message.FromPayload(Unmarshal.From(messageData.Data)); var totalTime = Stopwatch.StartNew(); var requestMetrics = Metrics.StartRequestMetrics(ConnectionMetrics); var receiveContext = new RelayEpoxyReceiveContext(this, ConnectionMetrics, requestMetrics); IBonded bondedLayerData = (layerData.Array == null) ? null : Unmarshal.From(layerData); ILayerStack layerStack; Error layerError = parentTransport.GetLayerStack(requestMetrics.request_id, out layerStack); if (layerError == null) { layerError = LayerStackUtils.ProcessOnReceive( layerStack, MessageType.EVENT, receiveContext, bondedLayerData, logger); } if (layerError != null) { logger.Site().Error( "{0}: Receiving event {1}/{2}.{3} failed due to layer error (Code: {4}, Message: {5}).", this, headers.conversation_id, headers.service_name, headers.method_name, layerError.error_code, layerError.message); return; } await serviceHost.DispatchEvent(headers.service_name, headers.method_name, receiveContext, request); Metrics.FinishRequestMetrics(requestMetrics, totalTime); metrics.Emit(requestMetrics); }); }
void DispatchResponse(EpoxyHeaders headers, EpoxyProtocol.MessageData messageData, ArraySegment <byte> layerData) { IMessage response = messageData.IsError ? Message.FromError(Unmarshal <Error> .From(messageData.Data)) : Message.FromPayload(Unmarshal.From(messageData.Data)); TaskCompletionSource <IMessage> tcs = responseMap.TakeTaskCompletionSource(headers.conversation_id); if (tcs == null) { logger.Site().Error( "{0} Response for unmatched request. Conversation ID: {1}", this, headers.conversation_id); return; } Task.Run( () => { var totalTime = Stopwatch.StartNew(); var requestMetrics = Metrics.StartRequestMetrics(ConnectionMetrics); var receiveContext = new RelayEpoxyReceiveContext(this, ConnectionMetrics, requestMetrics); IBonded bondedLayerData = (layerData.Array == null) ? null : Unmarshal.From(layerData); ILayerStack layerStack = tcs.Task.AsyncState as ILayerStack; Error layerError = LayerStackUtils.ProcessOnReceive(layerStack, MessageType.RESPONSE, receiveContext, bondedLayerData, logger); if (layerError != null) { logger.Site().Error( "{0} Receiving response {1}/{2}.{3} failed due to layer error (Code: {4}, Message: {5}).", this, headers.conversation_id, headers.service_name, headers.method_name, layerError.error_code, layerError.message); response = Message.FromError(layerError); } tcs.SetResult(response); Metrics.FinishRequestMetrics(requestMetrics, totalTime); metrics.Emit(requestMetrics); }); }
State?DispatchRequest(EpoxyHeaders headers, EpoxyProtocol.MessageData messageData, ArraySegment <byte> layerData) { Task.Run( async() => { var totalTime = Stopwatch.StartNew(); var requestMetrics = Metrics.StartRequestMetrics(ConnectionMetrics); var receiveContext = new RelayEpoxyReceiveContext(this, ConnectionMetrics, requestMetrics); ILayerStack layerStack = null; IMessage result; if (messageData.IsError) { logger.Site().Error( "{0} Received request with an error message. Only payload messages are allowed. Conversation ID: {1}", this, headers.conversation_id); result = Message.FromError( new Error { error_code = (int)ErrorCode.INVALID_INVOCATION, message = "Received request with an error message" }); } else { IMessage request = Message.FromPayload(Unmarshal.From(messageData.Data)); IBonded bondedLayerData = (layerData.Array == null) ? null : Unmarshal.From(layerData); Error layerError = parentTransport.GetLayerStack(requestMetrics.request_id, out layerStack); if (layerError == null) { layerError = LayerStackUtils.ProcessOnReceive( layerStack, MessageType.REQUEST, receiveContext, bondedLayerData, logger); } if (layerError == null) { result = await serviceHost.DispatchRequest(headers.service_name, headers.method_name, receiveContext, request); } else { logger.Site().Error( "{0} Receiving request {1}/{2}.{3} failed due to layer error (Code: {4}, Message: {5}).", this, headers.conversation_id, headers.service_name, headers.method_name, layerError.error_code, layerError.message); // Set layer error as result of this Bond method call and do not dispatch to method. // Since this error will be returned to client, cleanse out internal server error details, if any. result = Message.FromError(Errors.CleanseInternalServerError(layerError)); } } await SendReplyAsync(headers.conversation_id, result, layerStack, requestMetrics); Metrics.FinishRequestMetrics(requestMetrics, totalTime); metrics.Emit(requestMetrics); }); // no state change needed return(null); }