Exemple #1
0
        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);
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        /// <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++;
            }
        }
Exemple #5
0
        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);
        }