private async void DispatchRequest(InMemFrame payload, InMemFrameQueue queue) { var receiveContext = new SimpleInMemReceiveContext(connection); var headers = payload.headers; var layerData = payload.layerData; var message = payload.message; var taskSource = payload.outstandingRequest; ILayerStack layerStack; Error layerError = this.serviceHost.ParentTransport.GetLayerStack(out layerStack); if (layerError == null) { layerError = LayerStackUtils.ProcessOnReceive(layerStack, MessageType.Request, receiveContext, layerData, logger); } IMessage response; if (layerError == null) { response = await serviceHost.DispatchRequest(headers.method_name, receiveContext, message, connection.ConnectionMetrics); } else { logger.Site().Error("Receiving request {0}/{1} failed due to layer error (Code: {2}, Message: {3}).", headers.conversation_id, 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. response = Message.FromError(Errors.CleanseInternalServerError(layerError)); } SendReply(headers.conversation_id, response, taskSource, layerStack, queue); }
private async void DispatchRequest(InMemFrame payload, InMemFrameQueue queue) { var requestMetrics = Metrics.StartRequestMetrics(connection.ConnectionMetrics); var receiveContext = new SimpleInMemReceiveContext(connection, connection.ConnectionMetrics, requestMetrics); var headers = payload.headers; var layerData = payload.layerData; var message = payload.message; var taskSource = payload.outstandingRequest; ILayerStack layerStack; Error layerError = transport.GetLayerStack(requestMetrics.request_id, out layerStack); if (layerError == null) { layerError = LayerStackUtils.ProcessOnReceive(layerStack, MessageType.REQUEST, receiveContext, layerData, logger); } IMessage response; if (layerError == null) { response = await serviceHost.DispatchRequest(headers.service_name, headers.method_name, receiveContext, message); } else { logger.Site().Error("Receiving request {0}/{1}.{2} failed due to layer error (Code: {3}, Message: {4}).", 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. response = Message.FromError(Errors.CleanseInternalServerError(layerError)); } SendReply(headers.conversation_id, response, taskSource, layerStack, queue); }
internal void SendReply(ulong conversationId, IMessage response, TaskCompletionSource <IMessage> taskSource, ILayerStack layerStack, InMemFrameQueue queue) { var requestMetrics = Metrics.StartRequestMetrics(connection.ConnectionMetrics); var sendContext = new SimpleInMemSendContext(connection, connection.ConnectionMetrics, requestMetrics); IBonded layerData = null; Error layerError = LayerStackUtils.ProcessOnSend(layerStack, MessageType.RESPONSE, sendContext, out layerData, logger); // If there was a layer error, replace the response with the layer error if (layerError != null) { logger.Site().Error("Sending reply for conversation {0} failed due to layer error (Code: {1}, Message: {2}).", conversationId, layerError.error_code, layerError.message); // Set layer error as result of this Bond method call, replacing original response. // Since this error will be returned to client, cleanse out internal server error details, if any. response = Message.FromError(Errors.CleanseInternalServerError(layerError)); } var payload = Util.NewPayLoad(conversationId, SimpleInMemMessageType.RESPONSE, layerData, response, taskSource); queue.Enqueue(payload); }
/// <summary> /// A batch of <see cref="InMemFrame"/> instances are processed in each execution. They are dequeued from /// <see cref="SimpleInMemConnection.ReadQueue"/>. Single batch size is minimum of /// <see cref="MAXIMUM_BATCH_SIZE"/> and size of <see cref="SimpleInMemConnection.ReadQueue"/>. /// </summary> override internal void Process() { int batchIndex = 0; InMemFrameQueue readQueue = connection.ReadQueue; InMemFrameQueue writeQueue = connection.WriteQueue; if (readQueue == null || writeQueue == null) { return; } while (batchIndex < MAXIMUM_BATCH_SIZE && readQueue.Count > 0) { var payload = readQueue.Dequeue(); if (payload == null) { break; } switch (payload.headers.message_type) { case SimpleInMemMessageType.EVENT: Task.Run(() => DispatchEvent(payload)); break; case SimpleInMemMessageType.REQUEST: Task.Run(() => DispatchRequest(payload, writeQueue)); break; case SimpleInMemMessageType.RESPONSE: Task.Run(() => DispatchResponse(payload)); break; default: logger.Site().Error("Unsupported message type: [{0}], for conversation id: {1}.", payload.headers.message_type, payload.headers.conversation_id); break; } batchIndex++; } }
internal void SendReply(ulong conversationId, IMessage response, TaskCompletionSource<IMessage> taskSource, ILayerStack layerStack, InMemFrameQueue queue) { var sendContext = new SimpleInMemSendContext(connection); IBonded layerData = null; Error layerError = LayerStackUtils.ProcessOnSend(layerStack, MessageType.Response, sendContext, out layerData, logger); // If there was a layer error, replace the response with the layer error if (layerError != null) { logger.Site().Error("Sending reply for conversation {0} failed due to layer error (Code: {1}, Message: {2}).", conversationId, layerError.error_code, layerError.message); // Set layer error as result of this Bond method call, replacing original response. // Since this error will be returned to client, cleanse out internal server error details, if any. response = Message.FromError(Errors.CleanseInternalServerError(layerError)); } var payload = Util.NewPayLoad(conversationId, PayloadType.Response, layerData, response, taskSource); queue.Enqueue(payload); }