예제 #1
0
        private async Task RunClientMessagePump()
        {
            incomingMessagesThreadTimeTracking?.OnStartExecution();

            var reader = transport.GetReader(Message.Categories.Application);

            while (true)
            {
                try
                {
                    var moreTask = reader.WaitToReadAsync();
                    var more     = moreTask.IsCompletedSuccessfully ? moreTask.Result : await moreTask.ConfigureAwait(false);

                    if (!more)
                    {
                        incomingMessagesThreadTimeTracking?.OnStopExecution();
                        return;
                    }

                    // Continue reading if there're more messages
                    while (reader.TryRead(out var message))
                    {
                        if (message == null)
                        {
                            continue;
                        }
                        this.HandleMessage(message);
                    }
                }
                catch (Exception exception)
                {
                    this.logger.Error(ErrorCode.Runtime_Error_100326, "RunClientMessagePump has thrown exception. Continuing.", exception);
                }
            }
        }
예제 #2
0
        private void RunClientMessagePump(CancellationToken ct)
        {
            incomingMessagesThreadTimeTracking?.OnStartExecution();

            while (listenForMessages)
            {
                var message = transport.WaitMessage(Message.Categories.Application, ct);

                if (message == null) // if wait was cancelled
                {
                    break;
                }

                // when we receive the first message, we update the
                // clientId for this client because it may have been modified to
                // include the cluster name
                if (!firstMessageReceived)
                {
                    firstMessageReceived = true;
                    if (!handshakeClientId.Equals(message.TargetGrain))
                    {
                        clientId = message.TargetGrain;
                        transport.UpdateClientId(clientId);
                        CurrentActivationAddress = ActivationAddress.GetAddress(transport.MyAddress, clientId, CurrentActivationAddress.Activation);
                    }
                    else
                    {
                        clientId = handshakeClientId;
                    }
                }

                switch (message.Direction)
                {
                case Message.Directions.Response:
                {
                    ReceiveResponse(message);
                    break;
                }

                case Message.Directions.OneWay:
                case Message.Directions.Request:
                {
                    this.localObjects.Dispatch(message);
                    break;
                }

                default:
                    logger.Error(ErrorCode.Runtime_Error_100327, $"Message not supported: {message}.");
                    break;
                }
            }

            incomingMessagesThreadTimeTracking?.OnStopExecution();
        }
예제 #3
0
            public void ProcessReceived(SocketAsyncEventArgs e)
            {
#if TRACK_DETAILED_STATS
                ThreadTrackingStatistic tracker = null;
                if (StatisticsCollector.CollectThreadTimeTrackingStats)
                {
                    int id = System.Threading.Thread.CurrentThread.ManagedThreadId;
                    if (!trackers.TryGetValue(id, out tracker))
                    {
                        tracker = new ThreadTrackingStatistic("ThreadPoolThread." + System.Threading.Thread.CurrentThread.ManagedThreadId);
                        bool added = trackers.TryAdd(id, tracker);
                        if (added)
                        {
                            tracker.OnStartExecution();
                        }
                    }
                    tracker.OnStartProcessing();
                }
#endif
                try
                {
                    _buffer.UpdateReceivedData(e.Buffer, e.BytesTransferred);

                    Message msg;
                    while (_buffer.TryDecodeMessage(out msg))
                    {
                        IMA.HandleMessage(msg, Socket);
                    }
                }
                catch (Exception exc)
                {
                    try
                    {
                        // Log details of receive state machine
                        IMA.Log.Error(ErrorCode.MessagingProcessReceiveBufferException,
                                      $"Exception trying to process {e.BytesTransferred} bytes from endpoint {RemoteEndPoint}",
                                      exc);
                    }
                    catch (Exception) { }
                    _buffer.Reset(); // Reset back to a hopefully good base state

                    throw;
                }
#if TRACK_DETAILED_STATS
                finally
                {
                    if (StatisticsCollector.CollectThreadTimeTrackingStats)
                    {
                        tracker.IncrementNumberOfProcessed();
                        tracker.OnStopProcessing();
                    }
                }
#endif
            }
예제 #4
0
        private void RunClientMessagePump(CancellationToken ct)
        {
            if (StatisticsCollector.CollectThreadTimeTrackingStats)
            {
                incomingMessagesThreadTimeTracking.OnStartExecution();
            }
            while (listenForMessages)
            {
                var message = transport.WaitMessage(Message.Categories.Application, ct);

                if (message == null) // if wait was cancelled
                {
                    break;
                }
#if TRACK_DETAILED_STATS
                if (StatisticsCollector.CollectThreadTimeTrackingStats)
                {
                    incomingMessagesThreadTimeTracking.OnStartProcessing();
                }
#endif
                switch (message.Direction)
                {
                case Message.Directions.Response:
                {
                    ReceiveResponse(message);
                    break;
                }

                case Message.Directions.OneWay:
                case Message.Directions.Request:
                {
                    this.DispatchToLocalObject(message);
                    break;
                }

                default:
                    logger.Error(ErrorCode.Runtime_Error_100327, String.Format("Message not supported: {0}.", message));
                    break;
                }
#if TRACK_DETAILED_STATS
                if (StatisticsCollector.CollectThreadTimeTrackingStats)
                {
                    incomingMessagesThreadTimeTracking.OnStopProcessing();
                    incomingMessagesThreadTimeTracking.IncrementNumberOfProcessed();
                }
#endif
            }
            if (StatisticsCollector.CollectThreadTimeTrackingStats)
            {
                incomingMessagesThreadTimeTracking.OnStopExecution();
            }
        }
예제 #5
0
        private void RunClientMessagePump(CancellationToken ct)
        {
            if (StatisticsCollector.CollectThreadTimeTrackingStats)
            {
                incomingMessagesThreadTimeTracking.OnStartExecution();
            }
            while (listenForMessages)
            {
                var message = transport.WaitMessage(Message.Categories.Application, ct);

                if (message == null) // if wait was cancelled
                {
                    break;
                }
#if TRACK_DETAILED_STATS
                if (StatisticsCollector.CollectThreadTimeTrackingStats)
                {
                    incomingMessagesThreadTimeTracking.OnStartProcessing();
                }
#endif

                // when we receive the first message, we update the
                // clientId for this client because it may have been modified to
                // include the cluster name
                if (!firstMessageReceived)
                {
                    firstMessageReceived = true;
                    if (!handshakeClientId.Equals(message.TargetGrain))
                    {
                        clientId = message.TargetGrain;
                        transport.UpdateClientId(clientId);
                        CurrentActivationAddress = ActivationAddress.GetAddress(transport.MyAddress, clientId, CurrentActivationAddress.Activation);
                    }
                    else
                    {
                        clientId = handshakeClientId;
                    }
                }

                switch (message.Direction)
                {
                case Message.Directions.Response:
                {
                    ReceiveResponse(message);
                    break;
                }

                case Message.Directions.OneWay:
                case Message.Directions.Request:
                {
                    this.DispatchToLocalObject(message);
                    break;
                }

                default:
                    logger.Error(ErrorCode.Runtime_Error_100327, String.Format("Message not supported: {0}.", message));
                    break;
                }
#if TRACK_DETAILED_STATS
                if (StatisticsCollector.CollectThreadTimeTrackingStats)
                {
                    incomingMessagesThreadTimeTracking.OnStopProcessing();
                    incomingMessagesThreadTimeTracking.IncrementNumberOfProcessed();
                }
#endif
            }
            if (StatisticsCollector.CollectThreadTimeTrackingStats)
            {
                incomingMessagesThreadTimeTracking.OnStopExecution();
            }
        }
예제 #6
0
            public void ProcessReceived(SocketAsyncEventArgs e)
            {
#if TRACK_DETAILED_STATS
                ThreadTrackingStatistic tracker = null;
                if (StatisticsCollector.CollectThreadTimeTrackingStats)
                {
                    int id = System.Threading.Thread.CurrentThread.ManagedThreadId;
                    if (!trackers.TryGetValue(id, out tracker))
                    {
                        tracker = new ThreadTrackingStatistic("ThreadPoolThread." + System.Threading.Thread.CurrentThread.ManagedThreadId);
                        bool added = trackers.TryAdd(id, tracker);
                        if (added)
                        {
                            tracker.OnStartExecution();
                        }
                    }
                    tracker.OnStartProcessing();
                }
#endif
                try
                {
                    _buffer.UpdateReceivedData(e.Buffer, e.BytesTransferred);

                    while (true)
                    {
                        Message msg = null;
                        try
                        {
                            if (!this._buffer.TryDecodeMessage(out msg))
                            {
                                break;
                            }
                            this.IMA.HandleMessage(msg, this.Socket);
                        }
                        catch (Exception exception)
                        {
                            // If deserialization completely failed or the message was one-way, rethrow the exception
                            // so that it can be handled at another level.
                            if (msg?.Headers == null || msg.Direction != Message.Directions.Request)
                            {
                                throw;
                            }

                            // The message body was not successfully decoded, but the headers were.
                            // Send a fast fail to the caller.
                            MessagingStatisticsGroup.OnRejectedMessage(msg);
                            var response = this.messageFactory.CreateResponseMessage(msg);
                            response.Result     = Message.ResponseTypes.Error;
                            response.BodyObject = Response.ExceptionResponse(exception);

                            // Send the error response and continue processing the next message.
                            this.IMA.MessageCenter.SendMessage(response);
                        }
                    }
                }
                catch (Exception exc)
                {
                    try
                    {
                        // Log details of receive state machine
                        IMA.Log.Error(ErrorCode.MessagingProcessReceiveBufferException,
                                      $"Exception trying to process {e.BytesTransferred} bytes from endpoint {RemoteEndPoint}",
                                      exc);
                    }
                    catch (Exception) { }
                    _buffer.Reset(); // Reset back to a hopefully good base state

                    throw;
                }
#if TRACK_DETAILED_STATS
                finally
                {
                    if (StatisticsCollector.CollectThreadTimeTrackingStats)
                    {
                        tracker.IncrementNumberOfProcessed();
                        tracker.OnStopProcessing();
                    }
                }
#endif
            }
예제 #7
0
            public void ProcessReceivedBuffer(int bytes)
            {
                offset += bytes;
                if (offset < CurrentLength)
                {
                    return;                         // Nothing to do except start the next receive
                }
#if TRACK_DETAILED_STATS
                ThreadTrackingStatistic tracker = null;
                if (StatisticsCollector.CollectThreadTimeTrackingStats)
                {
                    int id = System.Threading.Thread.CurrentThread.ManagedThreadId;
                    if (!trackers.TryGetValue(id, out tracker))
                    {
                        tracker = new ThreadTrackingStatistic("ThreadPoolThread." + System.Threading.Thread.CurrentThread.ManagedThreadId);
                        bool added = trackers.TryAdd(id, tracker);
                        if (added)
                        {
                            tracker.OnStartExecution();
                        }
                    }
                    tracker.OnStartProcessing();
                }
#endif

                try
                {
                    if (batchingMode)
                    {
                        switch (phase)
                        {
                        case ReceivePhase.MetaHeader:
                            numberOfMessages = BitConverter.ToInt32(metaHeaderBuffer, 0);
                            lengthBuffer     = new byte[numberOfMessages * Message.LENGTH_HEADER_SIZE];
                            lengths          = new List <ArraySegment <byte> >()
                            {
                                new ArraySegment <byte>(lengthBuffer)
                            };
                            phase  = ReceivePhase.Lengths;
                            offset = 0;
                            break;

                        case ReceivePhase.Lengths:
                            headerBodies  = new List <ArraySegment <byte> >();
                            headerLengths = new int[numberOfMessages];
                            bodyLengths   = new int[numberOfMessages];

                            for (int i = 0; i < numberOfMessages; i++)
                            {
                                headerLengths[i]    = BitConverter.ToInt32(lengthBuffer, i * 8);
                                bodyLengths[i]      = BitConverter.ToInt32(lengthBuffer, i * 8 + 4);
                                headerBodiesLength += (headerLengths[i] + bodyLengths[i]);

                                // We need to set the boundary of ArraySegment<byte>s to the same as the header/body boundary
                                headerBodies.AddRange(BufferPool.GlobalPool.GetMultiBuffer(headerLengths[i]));
                                headerBodies.AddRange(BufferPool.GlobalPool.GetMultiBuffer(bodyLengths[i]));
                            }

                            phase  = ReceivePhase.HeaderBodies;
                            offset = 0;
                            break;

                        case ReceivePhase.HeaderBodies:
                            int lengtshSoFar = 0;

                            for (int i = 0; i < numberOfMessages; i++)
                            {
                                header        = ByteArrayBuilder.BuildSegmentListWithLengthLimit(headerBodies, lengtshSoFar, headerLengths[i]);
                                body          = ByteArrayBuilder.BuildSegmentListWithLengthLimit(headerBodies, lengtshSoFar + headerLengths[i], bodyLengths[i]);
                                lengtshSoFar += (headerLengths[i] + bodyLengths[i]);

                                var msg = new Message(header, body);
                                MessagingStatisticsGroup.OnMessageReceive(msg, headerLengths[i], bodyLengths[i]);

                                if (IMA.Log.IsVerbose3)
                                {
                                    IMA.Log.Verbose3("Received a complete message of {0} bytes from {1}", headerLengths[i] + bodyLengths[i], msg.SendingAddress);
                                }
                                if (headerLengths[i] + bodyLengths[i] > Message.LargeMessageSizeThreshold)
                                {
                                    IMA.Log.Info(ErrorCode.Messaging_LargeMsg_Incoming, "Receiving large message Size={0} HeaderLength={1} BodyLength={2}. Msg={3}",
                                                 headerLengths[i] + bodyLengths[i], headerLengths[i], bodyLengths[i], msg.ToString());
                                    if (IMA.Log.IsVerbose3)
                                    {
                                        IMA.Log.Verbose3("Received large message {0}", msg.ToLongString());
                                    }
                                }
                                IMA.HandleMessage(msg, Sock);
                            }
                            MessagingStatisticsGroup.OnMessageBatchReceive(IMA.SocketDirection, numberOfMessages, lengtshSoFar);

                            Reset();
                            break;
                        }
                    }
                    else
                    {
                        // We've completed a buffer. What we do depends on which phase we were in
                        switch (phase)
                        {
                        case ReceivePhase.Lengths:
                            // Pull out the header and body lengths
                            headerLength = BitConverter.ToInt32(lengthBuffer, 0);
                            bodyLength   = BitConverter.ToInt32(lengthBuffer, 4);
                            header       = BufferPool.GlobalPool.GetMultiBuffer(headerLength);
                            body         = BufferPool.GlobalPool.GetMultiBuffer(bodyLength);
                            phase        = ReceivePhase.Header;
                            offset       = 0;
                            break;

                        case ReceivePhase.Header:
                            phase  = ReceivePhase.Body;
                            offset = 0;
                            break;

                        case ReceivePhase.Body:
                            var msg = new Message(header, body);
                            MessagingStatisticsGroup.OnMessageReceive(msg, headerLength, bodyLength);

                            if (IMA.Log.IsVerbose3)
                            {
                                IMA.Log.Verbose3("Received a complete message of {0} bytes from {1}", headerLength + bodyLength, msg.SendingAddress);
                            }
                            if (headerLength + bodyLength > Message.LargeMessageSizeThreshold)
                            {
                                IMA.Log.Info(ErrorCode.Messaging_LargeMsg_Incoming, "Receiving large message Size={0} HeaderLength={1} BodyLength={2}. Msg={3}",
                                             headerLength + bodyLength, headerLength, bodyLength, msg.ToString());
                                if (IMA.Log.IsVerbose3)
                                {
                                    IMA.Log.Verbose3("Received large message {0}", msg.ToLongString());
                                }
                            }
                            IMA.HandleMessage(msg, Sock);
                            Reset();
                            break;
                        }
                    }
                }
                catch (Exception exc)
                {
                    try
                    {
                        // Log details of receive state machine
                        IMA.Log.Error(ErrorCode.MessagingProcessReceiveBufferException,
                                      string.Format(
                                          "Exception trying to process {0} bytes from endpoint {1} at offset {2} in phase {3}"
                                          + " CurrentLength={4} HeaderLength={5} BodyLength={6}",
                                          bytes, RemoteEndPoint, offset, phase,
                                          CurrentLength, headerLength, bodyLength
                                          ),
                                      exc);
                    }
                    catch (Exception) { }
                    Reset(); // Reset back to a hopefully good base state

                    throw;
                }
                finally
                {
#if TRACK_DETAILED_STATS
                    if (StatisticsCollector.CollectThreadTimeTrackingStats)
                    {
                        tracker.IncrementNumberOfProcessed();
                        tracker.OnStopProcessing();
                    }
#endif
                }
            }
            public void ProcessReceivedBuffer(int bytes)
            {
                if (bytes == 0)
                    return;

#if TRACK_DETAILED_STATS
                ThreadTrackingStatistic tracker = null;
                if (StatisticsCollector.CollectThreadTimeTrackingStats)
                {
                    int id = System.Threading.Thread.CurrentThread.ManagedThreadId;
                    if (!trackers.TryGetValue(id, out tracker))
                    {
                        tracker = new ThreadTrackingStatistic("ThreadPoolThread." + System.Threading.Thread.CurrentThread.ManagedThreadId);
                        bool added = trackers.TryAdd(id, tracker);
                        if (added)
                        {
                            tracker.OnStartExecution();
                        }
                    }
                    tracker.OnStartProcessing();
                }
#endif
                try
                {
                    _buffer.UpdateReceivedData(bytes);

                    Message msg;
                    while (_buffer.TryDecodeMessage(out msg))
                    {
                        IMA.HandleMessage(msg, Sock);
                    }
                }
                catch (Exception exc)
                {
                    try
                    {
                        // Log details of receive state machine
                        IMA.Log.Error(ErrorCode.MessagingProcessReceiveBufferException,
                            string.Format(
                            "Exception trying to process {0} bytes from endpoint {1}",
                                bytes, RemoteEndPoint),
                            exc);
                    }
                    catch (Exception) { }
                    _buffer.Reset(); // Reset back to a hopefully good base state

                    throw;
                }
#if TRACK_DETAILED_STATS
                finally
                {
                    if (StatisticsCollector.CollectThreadTimeTrackingStats)
                    {
                        tracker.IncrementNumberOfProcessed();
                        tracker.OnStopProcessing();
                    }
                }
#endif
            }