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 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); }
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); }
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); }
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); } }
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); } }
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(); }
protected abstract DuplicateContext DuplicateConnection(ListenerSessionConnection session);
internal IAsyncResult BeginDispatchSession(ListenerSessionConnection session, AsyncCallback callback, object state) { return(new DispatchSessionAsyncResult(session, callback, state)); }
internal IAsyncResult BeginDispatchSession(ListenerSessionConnection session, AsyncCallback callback, object state) { return new DispatchSessionAsyncResult(session, callback, state); }
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); } }