private async Task SendReplyAsync( ulong conversationId, IMessage response, ILayerStack layerStack, RequestMetrics requestMetrics) { var sendContext = new EpoxySendContext(this, ConnectionMetrics, requestMetrics); IBonded layerData; 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("{0} Sending reply for conversation ID {1} failed due to layer error (Code: {2}, Message: {3}).", this, 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 frame = MessageToFrame(conversationId, null, null, EpoxyMessageType.RESPONSE, response, layerData, logger); logger.Site().Debug("{0} Sending reply for conversation ID {1}.", this, conversationId); bool wasSent = await SendFrameAsync(frame); logger.Site().Debug("{0} Sending reply for conversation ID {1} {2}.", this, conversationId, wasSent ? "succeedeed" : "failed"); }
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); }
private 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 EpoxyReceiveContext(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); }
public override Error GetLayerStack(string uniqueId, out ILayerStack stack) { if (layerStackProvider != null) { return(layerStackProvider.GetLayerStack(uniqueId, out stack)); } stack = null; return(null); }
public override Error GetLayerStack(out ILayerStack stack) { if (layerStackProvider != null) { return(layerStackProvider.GetLayerStack(out stack)); } else { stack = null; return(null); } }
public Error GetLayerStack(out ILayerStack layerStack) { if (failAfterGets == 0) { layerStack = null; return(Errors.MakeInternalServerError(InternalDetails)); } else { failAfterGets--; layerStack = new LayerStack <Dummy>(LoggerTests.BlackHole, new TestLayer_StatefulAppend("foo")); return(null); } }
public Error GetLayerStack(string uniqueId, out ILayerStack layerStack, Logger logger) { if (failAfterGets == 0) { layerStack = null; return(Errors.MakeInternalServerError(InternalDetails, uniqueId)); } else { failAfterGets--; layerStack = new LayerStack <Dummy>(new TestLayer_StatefulAppend("foo")); return(null); } }
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); }); }
public static Error ProcessOnSend( ILayerStack layerStack, MessageType messageType, SendContext sendContext, out IBonded layerData, Logger logger) { Error error = null; layerData = null; if (layerStack != null) { error = layerStack.OnSend(messageType, sendContext, out layerData); if (error != null) { logger.Site().Warning("Layer error occurred sending message of type {0} (Code: {1} Message: {2}).", messageType, error.error_code, error.message); } } return error; }
public static Error ProcessOnSend(ILayerStack layerStack, MessageType messageType, SendContext sendContext, out IBonded layerData) { Error error = null; layerData = null; if (layerStack != null) { error = layerStack.OnSend(messageType, sendContext, out layerData); if (error != null) { Log.Warning("{0}.{1}: Layer error occurred sending message of type {2} (Code: {3} Message: {4}).", nameof(LayerStackUtils), nameof(ProcessOnSend), messageType, error.error_code, error.message); } } return(error); }
public static Error ProcessOnSend( ILayerStack layerStack, MessageType messageType, SendContext sendContext, out IBonded layerData, Logger logger) { Error error = null; layerData = null; if (layerStack != null) { error = layerStack.OnSend(messageType, sendContext, out layerData, logger); if (error != null) { logger.Site().Warning("Layer error occurred sending message of type {0} (Code: {1} Message: {2}).", messageType, error.error_code, error.message); } } return(error); }
private void DispatchResponse(EpoxyHeaders headers, ArraySegment <byte> payload, ArraySegment <byte> layerData) { IMessage response; if (headers.error_code != (int)ErrorCode.OK) { response = Message.FromError(Unmarshal <Error> .From(payload)); } else { response = Message.FromPayload(Unmarshal.From(payload)); } 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 receiveContext = new EpoxyReceiveContext(this); 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} failed due to layer error (Code: {3}, Message: {4}).", this, headers.conversation_id, headers.method_name, layerError.error_code, layerError.message); response = Message.FromError(layerError); } tcs.SetResult(response); }); }
private void DispatchResponse(InMemFrame payload) { var receiveContext = new SimpleInMemReceiveContext(connection); var headers = payload.headers; var layerData = payload.layerData; var message = payload.message; var taskSource = payload.outstandingRequest; ILayerStack layerStack = taskSource.Task.AsyncState as ILayerStack; Error layerError = LayerStackUtils.ProcessOnReceive(layerStack, MessageType.Response, receiveContext, layerData, logger); if (layerError != null) { logger.Site().Error("Receiving response {0}/{1} failed due to layer error (Code: {2}, Message: {3}).", headers.conversation_id, headers.method_name, layerError.error_code, layerError.message); message = Message.FromError(layerError); } payload.outstandingRequest.SetResult(message); }
public static Error ProcessOnReceive(ILayerStack layerStack, MessageType messageType, ReceiveContext receiveContext, IBonded layerData) { Error error = null; if (layerStack != null) { if (layerData == null) { Log.Warning("{0}.{1}: Layer stack present but no layer data received.", nameof(LayerStackUtils), nameof(ProcessOnReceive)); } error = layerStack.OnReceive(messageType, receiveContext, layerData); if (error != null) { Log.Warning("{0}.{1}: Layer error occurred receiving message of type {2} (Code: {3} Message: {4}).", nameof(LayerStackUtils), nameof(ProcessOnReceive), messageType, error.error_code, error.message); } } return(error); }
public static Error ProcessOnReceive( ILayerStack layerStack, MessageType messageType, ReceiveContext receiveContext, IBonded layerData, Logger logger) { Error error = null; if (layerStack != null) { if (layerData == null) { logger.Site().Warning("Layer stack present but no layer data received."); } error = layerStack.OnReceive(messageType, receiveContext, layerData, logger); if (error != null) { logger.Site().Warning("Layer error occurred receiving message of type {0} (Code: {1} Message: {2}).", messageType, error.error_code, error.message); } } return(error); }
public static Error ProcessOnReceive( ILayerStack layerStack, MessageType messageType, ReceiveContext receiveContext, IBonded layerData, Logger logger) { Error error = null; if (layerStack != null) { if (layerData == null) { logger.Site().Warning("Layer stack present but no layer data received."); } error = layerStack.OnReceive(messageType, receiveContext, layerData); if (error != null) { logger.Site().Warning("Layer error occurred receiving message of type {0} (Code: {1} Message: {2}).", messageType, error.error_code, error.message); } } return error; }
public Error GetLayerStack(string uniqueId, out ILayerStack stack) { Error error = null; if (cachedLayerStack != null) { stack = cachedLayerStack; } else { var layers = new ILayer <TLayerData> [layerProviders.Length]; for (int i = 0; i < layerProviders.Length; i++) { try { layers[i] = layerProviders[i].GetLayer(); if (layers[i] == null) { error = Errors.MakeInternalServerError($"Layer provider {i} produced null layer", uniqueId); logger.Site().Error(error.message); layers = null; break; } } catch (Exception ex) { logger.Site().Error(ex, "Layer provider {0} threw exception", i); error = Errors.MakeInternalServerError(ex, uniqueId, includeDetails: true); layers = null; break; } } stack = error == null ? new LayerStack <TLayerData>(logger, layers) : null; } return(error); }
public Error GetLayerStack(out ILayerStack stack) { Error error = null; if (cachedLayerStack != null) { stack = cachedLayerStack; } else { ILayer <TLayerData>[] layers; error = GetNewLayers(out layers); if (error == null) { stack = new LayerStack <TLayerData>(logger, layers); } else { stack = null; } } return(error); }
public static async Task <TestClientServer <TService> > SetupTestClientServer <TService>(ILayerStack serviceLayerStack = null, ILayerStack clientLayerStack = null) where TService : class, IService, new() { var testService = new TService(); EpoxyTransport serviceTransport = new EpoxyTransportBuilder() .SetLayerStack(serviceLayerStack) .Construct(); EpoxyListener listener = serviceTransport.MakeListener(new IPEndPoint(IPAddress.Loopback, 0)); listener.AddService(testService); await listener.StartAsync(); EpoxyTransport clientTransport = new EpoxyTransportBuilder() // some tests rely on the use of DebugExceptionHandler to assert things about the error message .SetLayerStack(clientLayerStack) .Construct(); EpoxyConnection clientConnection = await clientTransport.ConnectToAsync(listener.ListenEndpoint); return(new TestClientServer <TService> { Service = testService, ServiceTransport = serviceTransport, Listener = listener, ClientConnection = clientConnection, ClientTransport = clientTransport }); }
/// <summary> /// Set the layer stack. /// </summary> /// <param name="layerStack">The layer stack.</param> /// <returns>The builder.</returns> /// <remarks> /// The layer stack supplies the set of layers to be used /// by the built transport. May be null. /// </remarks> public virtual TransportBuilder <TTransport> SetLayerStack(ILayerStack layerStack) { LayerStack = layerStack; return(this); }
public EpoxyTransport(ILayerStack layerStack) { // Layer stack may be null this.layerStack = layerStack; }
/// <summary> /// Get a layer stack instance for this transport. /// </summary> /// <param name="uniqueId">A unique ID identifying the request or connection that triggered this call. Used in /// layer-originated errors.</param> /// <param name="stack">The layer stack instance. Will be null if an error is returned.</param> /// <returns>An error if one occurred, null otherwise.</returns> public abstract Error GetLayerStack(string uniqueId, out ILayerStack stack);
/// <summary> /// Get a layer stack instance for this transport. /// </summary> /// <param name="stack">The layer stack instance. Will be null if an error is returned.</param> /// <returns>An error if one occurred, null otherwise.</returns> public abstract Error GetLayerStack(out ILayerStack stack);
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); }