示例#1
0
        internal void OnDupHandle(ListenerSessionConnection session)
        {
            if (DiagnosticUtility.ShouldTraceInformation)
            {
                ListenerTraceUtility.TraceEvent(TraceEventType.Information, ListenerTraceCode.TransportListenerSessionsReceived, SR.GetString(SR.TraceCodeTransportListenerSessionsReceived), this);
            }

            if (TD.TransportListenerSessionsReceivedIsEnabled())
            {
                TD.TransportListenerSessionsReceived(session.EventTraceActivity, session.Via.ToString());
            }

            IPAddress     address;
            int           port;
            TransportType transportType = GetTransportTypeAndAddress(session.Connection, out address, out port);

            Debug.Print("TransportListener.OnDupHandle() via: " + session.Via.ToString() + " transportType: " + transportType);
            MessageQueue messageQueue = RoutingTable.Lookup(session.Via, address, port);

            if (messageQueue != null)
            {
                messageQueue.EnqueueSessionAndDispatch(session);
            }
            else
            {
                TransportListener.SendFault(session.Connection, FramingEncodingString.EndpointNotFoundFault);
                MessageQueue.OnDispatchFailure(transportType);
            }
        }
示例#2
0
        void StartDispatchSession(ListenerSessionConnection session)
        {
            if (TD.DispatchSessionStartIsEnabled())
            {
                TD.DispatchSessionStart(session.EventTraceActivity);
            }

            IAsyncResult dispatchAsyncResult = null;

            try
            {
                dispatchAsyncResult = session.WorkerProcess.BeginDispatchSession(session, dispatchSessionCompletedCallback, session);
            }
            catch (Exception exception)
            {
                if (Fx.IsFatal(exception))
                {
                    throw;
                }

                DiagnosticUtility.TraceHandledException(exception, TraceEventType.Warning);

                if (session.WorkerProcess.IsRegistered)
                {
                    // Add the worker back to the queue.
                    EnqueueWorkerAndDispatch(session.WorkerProcess, false);
                }
            }

            if (dispatchAsyncResult != null && dispatchAsyncResult.CompletedSynchronously)
            {
                CompleteDispatchSession(dispatchAsyncResult);
            }
        }
        void ContinueReading()
        {
            try
            {
                for (;;)
                {
                    if (size == 0)
                    {
                        if (readCallback == null)
                        {
                            readCallback = ReadCallback;
                        }

                        if (Connection.BeginRead(0, connectionBuffer.Length, GetRemainingTimeout(),
                                                 readCallback, this) == AsyncCompletionResult.Queued)
                        {
                            break;
                        }
                        GetReadResult();
                    }

                    Fx.Assert(size > 0, "");
                    for (;;)
                    {
                        int bytesDecoded = Decode(connectionBuffer, offset, size);
                        if (bytesDecoded > 0)
                        {
                            offset += bytesDecoded;
                            size   -= bytesDecoded;
                        }

                        Uri via = null;
                        if (CanDupHandle(out via))
                        {
                            ListenerSessionConnection session = new ListenerSessionConnection(
                                this.Connection, this.dataRead, via, this.GetConnectionDequeuedCallback());
                            viaDecodedCallback(this, session);
                            this.ReleaseConnection();
                            return;
                        }

                        if (size == 0)
                        {
                            break;
                        }
                    }
                }
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    throw;
                }

                AbortAndCount(e);
            }
        }
        protected override DuplicateContext DuplicateConnection(ListenerSessionConnection session)
        {
            SocketInformation dupedSocket = default(SocketInformation);

            try
            {
                dupedSocket = (SocketInformation)session.Connection.DuplicateAndClose(this.ProcessId);
            }
#pragma warning suppress 56500 // covered by FxCOP
            catch (Exception exception)
            {
                if (Fx.IsFatal(exception))
                {
                    throw;
                }

                // this normally happens if:
                // A) we don't have rights to duplicate handles to the WorkerProcess NativeErrorCode == 10022
                // B) we fail to duplicate handle because the WorkerProcess is exiting/exited NativeErrorCode == 10024
                // - in the self hosted case: report error to the client
                // - in the web hosted case: roundrobin to the next available WorkerProcess (if this WorkerProcess is down?)
#if DEBUG
                if (exception is SocketException)
                {
                    Debug.Print("TcpWorkerProcess.DuplicateConnection() failed duplicating socket for processId: " + this.ProcessId + " errorCode:" + ((SocketException)exception).NativeErrorCode + " exception:" + exception.Message);
                }
#endif
                if (DiagnosticUtility.ShouldTraceError)
                {
                    ListenerTraceUtility.TraceEvent(TraceEventType.Error, ListenerTraceCode.MessageQueueDuplicatedSocketError, SR.GetString(SR.TraceCodeMessageQueueDuplicatedSocketError), this, exception);
                }
                if (TD.MessageQueueDuplicatedSocketErrorIsEnabled())
                {
                    TD.MessageQueueDuplicatedSocketError(session.EventTraceActivity);
                }


                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ServiceActivationException(SR.GetString(SR.MessageQueueDuplicatedSocketError), exception));
            }

            if (DiagnosticUtility.ShouldTraceInformation)
            {
                ListenerTraceUtility.TraceEvent(TraceEventType.Information, ListenerTraceCode.MessageQueueDuplicatedSocket, SR.GetString(SR.TraceCodeMessageQueueDuplicatedSocket), this);
            }
            if (TD.MessageQueueDuplicatedSocketCompleteIsEnabled())
            {
                TD.MessageQueueDuplicatedSocketComplete(session.EventTraceActivity);
            }

            return(new TcpDuplicateContext(dupedSocket, session.Via, session.Data));
        }
        protected override DuplicateContext DuplicateConnection(ListenerSessionConnection session)
        {
            SocketInformation dupedSocket = default(SocketInformation);
            try
            {
                dupedSocket = (SocketInformation)session.Connection.DuplicateAndClose(this.ProcessId);
            }
#pragma warning suppress 56500 // covered by FxCOP
            catch (Exception exception)
            {
                if (Fx.IsFatal(exception))
                {
                    throw;
                }

                // this normally happens if:
                // A) we don't have rights to duplicate handles to the WorkerProcess NativeErrorCode == 10022
                // B) we fail to duplicate handle because the WorkerProcess is exiting/exited NativeErrorCode == 10024
                // - in the self hosted case: report error to the client
                // - in the web hosted case: roundrobin to the next available WorkerProcess (if this WorkerProcess is down?)
#if DEBUG
                if (exception is SocketException)
                {
                    Debug.Print("TcpWorkerProcess.DuplicateConnection() failed duplicating socket for processId: " + this.ProcessId + " errorCode:" + ((SocketException)exception).NativeErrorCode + " exception:" + exception.Message);
                }
#endif
                if (DiagnosticUtility.ShouldTraceError)
                {
                    ListenerTraceUtility.TraceEvent(TraceEventType.Error, ListenerTraceCode.MessageQueueDuplicatedSocketError, SR.GetString(SR.TraceCodeMessageQueueDuplicatedSocketError), this, exception);
                }
                if (TD.MessageQueueDuplicatedSocketErrorIsEnabled())
                {                    
                    TD.MessageQueueDuplicatedSocketError(session.EventTraceActivity);
                }


                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ServiceActivationException(SR.GetString(SR.MessageQueueDuplicatedSocketError), exception));
            }

            if (DiagnosticUtility.ShouldTraceInformation)
            {
                ListenerTraceUtility.TraceEvent(TraceEventType.Information, ListenerTraceCode.MessageQueueDuplicatedSocket, SR.GetString(SR.TraceCodeMessageQueueDuplicatedSocket), this);
            }
            if (TD.MessageQueueDuplicatedSocketCompleteIsEnabled())
            {
                TD.MessageQueueDuplicatedSocketComplete(session.EventTraceActivity);
            }

            return new TcpDuplicateContext(dupedSocket, session.Via, session.Data);
        }
示例#6
0
        void CompleteDispatchSession(IAsyncResult result)
        {
            ListenerSessionConnection session = (ListenerSessionConnection)result.AsyncState;

            Fx.Assert(session.WorkerProcess != null, "The WorkerProcess should be set on the message.");

            bool success = session.WorkerProcess.EndDispatchSession(result);

            TraceDispatchCompleted(success, session);

            if (!success)
            {
                OnConnectionDispatchFailed(session.Connection);
            }

            EnqueueWorkerAndDispatch(session.WorkerProcess, !result.CompletedSynchronously);
        }
示例#7
0
 void TraceDispatchCompleted(bool success, ListenerSessionConnection session)
 {
     if (success)
     {
         if (TD.DispatchSessionSuccessIsEnabled())
         {
             TD.DispatchSessionSuccess(session.EventTraceActivity);
         }
     }
     else
     {
         if (TD.DispatchSessionFailedIsEnabled())
         {
             TD.DispatchSessionFailed(session.EventTraceActivity);
         }
     }
 }
        protected override DuplicateContext DuplicateConnection(ListenerSessionConnection session)
        {
            IntPtr dupedPipe = IntPtr.Zero;

            try
            {
                dupedPipe = (IntPtr)session.Connection.DuplicateAndClose(this.ProcessId);
            }
#pragma warning suppress 56500 // covered by FxCOP
            catch (Exception exception)
            {
                if (Fx.IsFatal(exception))
                {
                    throw;
                }

                // this normally happens if:
                // A) we don't have rights to duplicate handles to the WorkerProcess NativeErrorCode == 87
                // B) we fail to duplicate handle because the WorkerProcess is exiting/exited NativeErrorCode == ???
                // - in the self hosted case: report error to the client
                // - in the web hosted case: roundrobin to the next available WorkerProcess (if this WorkerProcess is down?)
#if DEBUG
                if (exception is CommunicationException)
                {
                    int errorCode = ((System.IO.PipeException)exception.InnerException).ErrorCode;
                    Debug.Print("NamedPipeWorkerProcess.DuplicateConnection() failed duplicating pipe for processId: " + this.ProcessId + " errorCode:" + errorCode + " exception:" + exception.Message);
                }
#endif
                if (DiagnosticUtility.ShouldTraceError)
                {
                    ListenerTraceUtility.TraceEvent(TraceEventType.Error, ListenerTraceCode.MessageQueueDuplicatedPipe, SR.GetString(SR.TraceCodeMessageQueueDuplicatedPipe), this, exception);
                }

                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ServiceActivationException(SR.GetString(SR.MessageQueueDuplicatedPipeError), exception));
            }

            if (DiagnosticUtility.ShouldTraceInformation)
            {
                ListenerTraceUtility.TraceEvent(TraceEventType.Information, ListenerTraceCode.MessageQueueDuplicatedPipe, SR.GetString(SR.TraceCodeMessageQueueDuplicatedPipe), this);
            }

            return(new NamedPipeDuplicateContext(dupedPipe, session.Via, session.Data));
        }
        protected override DuplicateContext DuplicateConnection(ListenerSessionConnection session)
        {
            IntPtr dupedPipe = IntPtr.Zero;
            try
            {
                dupedPipe = (IntPtr)session.Connection.DuplicateAndClose(this.ProcessId);
            }
#pragma warning suppress 56500 // covered by FxCOP
            catch (Exception exception)
            {
                if (Fx.IsFatal(exception))
                {
                    throw;
                }

                // this normally happens if:
                // A) we don't have rights to duplicate handles to the WorkerProcess NativeErrorCode == 87
                // B) we fail to duplicate handle because the WorkerProcess is exiting/exited NativeErrorCode == ???
                // - in the self hosted case: report error to the client
                // - in the web hosted case: roundrobin to the next available WorkerProcess (if this WorkerProcess is down?)
#if DEBUG
                if (exception is CommunicationException)
                {
                    int errorCode = ((System.IO.PipeException)exception.InnerException).ErrorCode;
                    Debug.Print("NamedPipeWorkerProcess.DuplicateConnection() failed duplicating pipe for processId: " + this.ProcessId + " errorCode:" + errorCode + " exception:" + exception.Message);
                }
#endif
                if (DiagnosticUtility.ShouldTraceError)
                {
                    ListenerTraceUtility.TraceEvent(TraceEventType.Error, ListenerTraceCode.MessageQueueDuplicatedPipe, SR.GetString(SR.TraceCodeMessageQueueDuplicatedPipe), this, exception);
                }

                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ServiceActivationException(SR.GetString(SR.MessageQueueDuplicatedPipeError), exception));
            }

            if (DiagnosticUtility.ShouldTraceInformation)
            {
                ListenerTraceUtility.TraceEvent(TraceEventType.Information, ListenerTraceCode.MessageQueueDuplicatedPipe, SR.GetString(SR.TraceCodeMessageQueueDuplicatedPipe), this);
            }

            return new NamedPipeDuplicateContext(dupedPipe, session.Via, session.Data);
        }
示例#10
0
            public DispatchSessionAsyncResult(ListenerSessionConnection session, AsyncCallback callback, object state)
                : base(callback, state)
            {
                this.session = session;
                DuplicateContext duplicateContext = null;

                try
                {
                    duplicateContext = session.WorkerProcess.DuplicateConnection(session);
                }
                catch (ServiceActivationException e)
                {
                    int    traceCode;
                    string traceDescription;
                    if (session.WorkerProcess is TcpWorkerProcess)
                    {
                        traceCode        = ListenerTraceCode.MessageQueueDuplicatedSocketError;
                        traceDescription = SR.GetString(SR.TraceCodeMessageQueueDuplicatedSocketError);
                    }
                    else
                    {
                        traceCode        = ListenerTraceCode.MessageQueueDuplicatedPipeError;
                        traceDescription = SR.GetString(SR.TraceCodeMessageQueueDuplicatedPipeError);
                    }

                    if (DiagnosticUtility.ShouldTraceError)
                    {
                        ListenerTraceUtility.TraceEvent(TraceEventType.Error, traceCode, traceDescription, this, e);
                    }
                    this.Complete(true, e);
                    return;
                }

                IAsyncResult result = this.session.WorkerProcess.ConnectionDuplicator.BeginDuplicate(duplicateContext,
                                                                                                     dispatchSessionCallback, this);

                if (result.CompletedSynchronously)
                {
                    CompleteDuplicateSession(result);
                    this.Complete(true);
                }
            }
        void OnViaDecoded(InitialServerConnectionReader connectionReader, ListenerSessionConnection session)
        {
            try
            {
                connectionHandleDuplicated(session);
            }
            finally
            {
                session.TriggerDequeuedCallback();
            }
            lock (ThisLock)
            {
                if (isDisposed)
                {
                    return;
                }

                connectionReaders.Remove(connectionReader);
            }
        }
示例#12
0
        void DispatchSession()
        {
            for (;;)
            {
                ListenerSessionConnection session = null;
                lock (SessionLock)
                {
                    if (sessionMessages.Count > 0)
                    {
                        WorkerProcess worker = null;
                        while (sessionWorkers.Count > 0)
                        {
                            worker = sessionWorkers.Dequeue();
                            if (worker.IsRegistered)
                            {
                                break;
                            }
                            worker = null;
                        }

                        if (worker == null)
                        {
                            // There is no more active worker. So break the loop.
                            break;
                        }

                        // For better performance, we may want to check whether the message has been timed out in the future.
                        session = sessionMessages.Dequeue();
                        session.WorkerProcess = worker;
                    }
                }

                if (session == null)
                {
                    // There is mo more message left. So break the loop.
                    break;
                }

                StartDispatchSession(session);
            }
        }
示例#13
0
        internal void EnqueueSessionAndDispatch(ListenerSessionConnection session)
        {
            lock (SessionLock)
            {
                if (!CanDispatch)
                {
                    TransportListener.SendFault(session.Connection, FramingEncodingString.EndpointUnavailableFault);
                    OnDispatchFailure(transportType);
                    return;
                }
                else if (sessionMessages.Count >= maxQueueSize)
                {
                    // Abort the connection when the queue is full.
                    if (TD.PendingSessionQueueFullIsEnabled())
                    {
                        TD.PendingSessionQueueFull(session.EventTraceActivity,
                                                   (session.Via != null) ? session.Via.ToString() : string.Empty,
                                                   sessionMessages.Count);
                    }
                    session.Connection.Abort();
                    OnDispatchFailure(transportType);
                    return;
                }
                else
                {
                    sessionMessages.Enqueue(session);
                    if (TD.PendingSessionQueueRatioIsEnabled())
                    {
                        TD.PendingSessionQueueRatio(sessionMessages.Count, maxQueueSize);
                    }
                }
            }

            OnSessionEnqueued();
            DispatchSession();
        }
        internal void EnqueueSessionAndDispatch(ListenerSessionConnection session)
        {
            lock (SessionLock)
            {
                if (!CanDispatch)
                {
                    TransportListener.SendFault(session.Connection, FramingEncodingString.EndpointUnavailableFault);
                    OnDispatchFailure(transportType);
                    return;
                }
                else if (sessionMessages.Count >= maxQueueSize)
                {
                    // Abort the connection when the queue is full.
                    if (TD.PendingSessionQueueFullIsEnabled())
                    {
                        TD.PendingSessionQueueFull(session.EventTraceActivity,
                            (session.Via != null) ? session.Via.ToString() : string.Empty,
                            sessionMessages.Count);
                    }
                    session.Connection.Abort();
                    OnDispatchFailure(transportType);
                    return;
                }
                else
                {
                    sessionMessages.Enqueue(session);
                    if (TD.PendingSessionQueueRatioIsEnabled())
                    {
                        TD.PendingSessionQueueRatio(sessionMessages.Count, maxQueueSize);
                    }
                }
            }

            OnSessionEnqueued();
            DispatchSession();
        }
示例#15
0
 protected abstract DuplicateContext DuplicateConnection(ListenerSessionConnection session);
示例#16
0
 internal IAsyncResult BeginDispatchSession(ListenerSessionConnection session, AsyncCallback callback, object state)
 {
     return(new DispatchSessionAsyncResult(session, callback, state));
 }
示例#17
0
            public DispatchSessionAsyncResult(ListenerSessionConnection session, AsyncCallback callback, object state)
                : base(callback, state)
            {
                this.session = session;
                DuplicateContext duplicateContext = null;
                try
                {
                    duplicateContext = session.WorkerProcess.DuplicateConnection(session);
                }
                catch (ServiceActivationException e)
                {
                    int traceCode;
                    string traceDescription;
                    if (session.WorkerProcess is TcpWorkerProcess)
                    {
                        traceCode = ListenerTraceCode.MessageQueueDuplicatedSocketError;
                        traceDescription = SR.GetString(SR.TraceCodeMessageQueueDuplicatedSocketError);
                    }
                    else
                    {
                        traceCode = ListenerTraceCode.MessageQueueDuplicatedPipeError;
                        traceDescription = SR.GetString(SR.TraceCodeMessageQueueDuplicatedPipeError);
                    }

                    if (DiagnosticUtility.ShouldTraceError)
                    {
                        ListenerTraceUtility.TraceEvent(TraceEventType.Error, traceCode, traceDescription, this, e);
                    }
                    this.Complete(true, e);
                    return;
                }

                IAsyncResult result = this.session.WorkerProcess.ConnectionDuplicator.BeginDuplicate(duplicateContext,
                    dispatchSessionCallback, this);

                if (result.CompletedSynchronously)
                {
                    CompleteDuplicateSession(result);
                    this.Complete(true);
                }
            }
 void TraceDispatchCompleted(bool success, ListenerSessionConnection session)
 {
     if (success)
     {
         if (TD.DispatchSessionSuccessIsEnabled())
         {
             TD.DispatchSessionSuccess(session.EventTraceActivity);
         }
     }
     else
     {
         if (TD.DispatchSessionFailedIsEnabled())
         {
             TD.DispatchSessionFailed(session.EventTraceActivity);
         }
     }
 }
示例#19
0
 protected abstract DuplicateContext DuplicateConnection(ListenerSessionConnection session);
示例#20
0
 internal IAsyncResult BeginDispatchSession(ListenerSessionConnection session, AsyncCallback callback, object state)
 {
     return new DispatchSessionAsyncResult(session, callback, state);
 }
示例#21
0
        void ContinueReading()
        {
            try
            {
                for (;;)
                {
                    if (size == 0)
                    {
                        if (readCallback == null)
                            readCallback = ReadCallback;

                        if (Connection.BeginRead(0, connectionBuffer.Length, GetRemainingTimeout(),
                            readCallback, this) == AsyncCompletionResult.Queued)
                        {
                            break;
                        }
                        GetReadResult();
                    }

                    Fx.Assert(size > 0, "");
                    for (;;)
                    {
                        int bytesDecoded = Decode(connectionBuffer, offset, size);
                        if (bytesDecoded > 0)
                        {
                            offset += bytesDecoded;
                            size -= bytesDecoded;
                        }

                        Uri via = null;
                        if (CanDupHandle(out via))
                        {
                            ListenerSessionConnection session = new ListenerSessionConnection(
                                this.Connection, this.dataRead, via, this.GetConnectionDequeuedCallback());
                            viaDecodedCallback(this, session);
                            this.ReleaseConnection();
                            return;
                        }

                        if (size == 0)
                            break;
                    }
                }
            }
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    throw;
                }

                AbortAndCount(e);
            }
        }
        internal void OnDupHandle(ListenerSessionConnection session)
        {
            if (DiagnosticUtility.ShouldTraceInformation)
            {
                ListenerTraceUtility.TraceEvent(TraceEventType.Information, ListenerTraceCode.TransportListenerSessionsReceived, SR.GetString(SR.TraceCodeTransportListenerSessionsReceived), this);
            }

            if (TD.TransportListenerSessionsReceivedIsEnabled())
            {
                TD.TransportListenerSessionsReceived(session.EventTraceActivity, session.Via.ToString());
            }

            IPAddress address;
            int port;
            TransportType transportType = GetTransportTypeAndAddress(session.Connection, out address, out port);
            Debug.Print("TransportListener.OnDupHandle() via: " + session.Via.ToString() + " transportType: " + transportType);
            MessageQueue messageQueue = RoutingTable.Lookup(session.Via, address, port);
            if (messageQueue != null)
            {
                messageQueue.EnqueueSessionAndDispatch(session);
            }
            else
            {
                TransportListener.SendFault(session.Connection, FramingEncodingString.EndpointNotFoundFault);
                MessageQueue.OnDispatchFailure(transportType);
            }
        }
        void OnViaDecoded(InitialServerConnectionReader connectionReader, ListenerSessionConnection session)
        {
            try
            {
                connectionHandleDuplicated(session);
            }
            finally
            {
                session.TriggerDequeuedCallback();
            }
            lock (ThisLock)
            {
                if (isDisposed)
                {
                    return;
                }

                connectionReaders.Remove(connectionReader);
            }
        }
        void StartDispatchSession(ListenerSessionConnection session)
        {
            if (TD.DispatchSessionStartIsEnabled())
            {
                TD.DispatchSessionStart(session.EventTraceActivity);
            }

            IAsyncResult dispatchAsyncResult = null;
            try
            {
                dispatchAsyncResult = session.WorkerProcess.BeginDispatchSession(session, dispatchSessionCompletedCallback, session);
            }
            catch (Exception exception)
            {
                if (Fx.IsFatal(exception))
                {
                    throw;
                }

                DiagnosticUtility.TraceHandledException(exception, TraceEventType.Warning);

                if (session.WorkerProcess.IsRegistered)
                {
                    // Add the worker back to the queue.
                    EnqueueWorkerAndDispatch(session.WorkerProcess, false);
                }
            }

            if (dispatchAsyncResult != null && dispatchAsyncResult.CompletedSynchronously)
            {
                CompleteDispatchSession(dispatchAsyncResult);
            }
        }