private Task ProcessMessages(ITransportConnection connection, Func <Task> initialize) { var disposer = new Disposer(); if (BeforeCancellationTokenCallbackRegistered != null) { BeforeCancellationTokenCallbackRegistered(); } var cancelContext = new ForeverTransportContext(this, disposer); // Ensure delegate continues to use the C# Compiler static delegate caching optimization. IDisposable registration = ConnectionEndToken.SafeRegister(state => Cancel(state), cancelContext); var messageContext = new MessageContext(this, _transportLifetime, registration); if (BeforeReceive != null) { BeforeReceive(); } try { // Ensure we enqueue the response initialization before any messages are received EnqueueOperation(state => InitializeResponse((ITransportConnection)state), connection) .Catch((ex, state) => OnError(ex, state), messageContext); // Ensure delegate continues to use the C# Compiler static delegate caching optimization. IDisposable subscription = connection.Receive(LastMessageId, (response, state) => OnMessageReceived(response, state), MaxMessages, messageContext); disposer.Set(subscription); if (AfterReceive != null) { AfterReceive(); } // Ensure delegate continues to use the C# Compiler static delegate caching optimization. initialize().Then(tcs => tcs.TrySetResult(null), InitializeTcs) .Catch((ex, state) => OnError(ex, state), messageContext); } catch (OperationCanceledException ex) { InitializeTcs.TrySetCanceled(); _transportLifetime.Complete(ex); } catch (Exception ex) { InitializeTcs.TrySetCanceled(); _transportLifetime.Complete(ex); } return(_requestLifeTime.Task); }
private Task ProcessMessages(ITransportConnection connection, Func <Task> initialize) { var disposer = new Disposer(); var cancelContext = new LongPollingTransportContext(this, disposer); // Ensure delegate continues to use the C# Compiler static delegate caching optimization. IDisposable registration = ConnectionEndToken.SafeRegister(state => Cancel(state), cancelContext); var lifeTime = new RequestLifetime(this, _requestLifeTime, registration); var messageContext = new MessageContext(this, lifeTime); try { // Ensure delegate continues to use the C# Compiler static delegate caching optimization. IDisposable subscription = connection.Receive(MessageId, (response, state) => OnMessageReceived(response, state), MaxMessages, messageContext); // Set the disposable disposer.Set(subscription); // Ensure delegate continues to use the C# Compiler static delegate caching optimization. initialize().Catch((ex, state) => OnError(ex, state), messageContext); } catch (Exception ex) { lifeTime.Complete(ex); } return(_requestLifeTime.Task); }
private void ProcessMessages(ITransportConnection connection, Func <Task> postReceive, Action endRequest) { IDisposable subscription = null; var wh = new ManualResetEventSlim(initialState: false); // End the request if the connection end token is triggered CancellationTokenRegistration registration = ConnectionEndToken.Register(() => { wh.Wait(); subscription.Dispose(); }); subscription = connection.Receive(LastMessageId, response => { // We need to wait until post receive has been called wh.Wait(); response.TimedOut = IsTimedOut; if (response.Disconnect || response.TimedOut || response.Aborted || ConnectionEndToken.IsCancellationRequested) { if (response.Aborted) { // If this was a clean disconnect raise the event. OnDisconnect(); } endRequest(); registration.Dispose(); subscription.Dispose(); return(TaskAsyncHelper.False); } else { return(Send(response).Then(() => TaskAsyncHelper.True)); } }, MaxMessages); if (postReceive != null) { postReceive().Catch(_allErrorsTotalCounter, _allErrorsPerSecCounter) .ContinueWith(task => wh.Set()); } else { wh.Set(); } }
private Task ProcessMessages(ITransportConnection connection, Func <Task> initialize) { var disposer = new Disposer(); if (BeforeCancellationTokenCallbackRegistered != null) { BeforeCancellationTokenCallbackRegistered(); } var cancelContext = new ForeverTransportContext(this, disposer); // Ensure delegate continues to use the C# Compiler static delegate caching optimization. _busRegistration = ConnectionEndToken.SafeRegister(state => Cancel(state), cancelContext); if (BeforeReceive != null) { BeforeReceive(); } try { // Ensure we enqueue the response initialization before any messages are received EnqueueOperation(state => InitializeResponse((ITransportConnection)state), connection) .Catch((ex, state) => ((ForeverTransport)state).OnError(ex), this, Logger); // Ensure delegate continues to use the C# Compiler static delegate caching optimization. IDisposable subscription = connection.Receive(LastMessageId, (response, state) => ((ForeverTransport)state).OnMessageReceived(response), MaxMessages, this); if (AfterReceive != null) { AfterReceive(); } // Ensure delegate continues to use the C# Compiler static delegate caching optimization. initialize().Catch((ex, state) => ((ForeverTransport)state).OnError(ex), this, Logger) .Finally(state => ((SubscriptionDisposerContext)state).Set(), new SubscriptionDisposerContext(disposer, subscription)); } catch (Exception ex) { _transportLifetime.Complete(ex); } return(_requestLifeTime.Task); }
private void ProcessMessages(ITransportConnection connection, Func <Task> postReceive, Action endRequest) { IDisposable subscription = null; var wh = new ManualResetEventSlim(initialState: false); // End the request if the connection end token is triggered CancellationTokenRegistration registration = ConnectionEndToken.Register(() => { wh.Wait(); subscription.Dispose(); }); subscription = connection.Receive(LastMessageId, response => { // We need to wait until post receive has been called wh.Wait(); response.TimedOut = IsTimedOut; // If we're telling the client to disconnect then clean up the instantiated connection. if (response.Disconnect) { // Send the response before removing any connection data return(Send(response).Then(() => { // Remove connection without triggering disconnect HeartBeat.RemoveConnection(this); endRequest(); // Dispose everything registration.Dispose(); subscription.Dispose(); return TaskAsyncHelper.False; })); } else if (response.TimedOut || response.Aborted || ConnectionEndToken.IsCancellationRequested) { if (response.Aborted) { // If this was a clean disconnect raise the event. OnDisconnect(); } endRequest(); // Dispose everything registration.Dispose(); subscription.Dispose(); return(TaskAsyncHelper.False); } else { return(Send(response).Then(() => TaskAsyncHelper.True)); } }, MaxMessages); if (postReceive != null) { postReceive().Catch(_counters.ErrorsAllTotal, _counters.ErrorsAllPerSec) .ContinueWith(task => wh.Set()); } else { wh.Set(); } }
private void ProcessMessages(ITransportConnection connection, Func <Task> postReceive, Action <Exception> endRequest) { IDisposable subscription = null; IDisposable registration = null; var wh = new ManualResetEventSlim(); if (BeforeReceive != null) { BeforeReceive(); } try { subscription = connection.Receive(LastMessageId, response => { // We need to wait until post receive has been called wh.Wait(); response.TimedOut = IsTimedOut; // If we're telling the client to disconnect then clean up the instantiated connection. if (response.Disconnect) { // Send the response before removing any connection data return(Send(response).Then(() => { registration.Dispose(); // Remove connection without triggering disconnect Heartbeat.RemoveConnection(this); endRequest(null); return TaskAsyncHelper.False; })); } else if (response.TimedOut || response.Aborted || ConnectionEndToken.IsCancellationRequested) { // If this is null it's because the cancellation token tripped // before we setup the registration at all. if (registration != null) { registration.Dispose(); } if (response.Aborted) { // If this was a clean disconnect raise the event. OnDisconnect(); } endRequest(null); return(TaskAsyncHelper.False); } else { return(Send(response).Then(() => TaskAsyncHelper.True) .Catch(IncrementErrorCounters) .Catch(ex => { Trace.TraceInformation("Send failed for {0} with: {1}", ConnectionId, ex.GetBaseException()); })); } }, MaxMessages); } catch (Exception ex) { endRequest(ex); wh.Set(); return; } if (AfterReceive != null) { AfterReceive(); } if (postReceive != null) { postReceive().Catch(_counters.ErrorsAllTotal, _counters.ErrorsAllPerSec) .Catch(ex => endRequest(ex)) .Catch(ex => { Trace.TraceInformation("Failed post receive for {0} with: {1}", ConnectionId, ex.GetBaseException()); }) .ContinueWith(task => wh.Set()); } else { wh.Set(); } if (BeforeCancellationTokenCallbackRegistered != null) { BeforeCancellationTokenCallbackRegistered(); } // This has to be done last incase it runs synchronously. registration = ConnectionEndToken.SafeRegister(state => { Trace.TraceInformation("Cancel(" + ConnectionId + ")"); state.Dispose(); }, subscription); }
private void ProcessMessages(ITransportConnection connection, Func <Task> postReceive, Action <Exception> endRequest) { IDisposable subscription = null; var wh = new ManualResetEventSlim(initialState: false); var registration = default(CancellationTokenRegistration); bool disposeSubscriptionImmediately = false; try { // End the request if the connection end token is triggered registration = ConnectionEndToken.Register(() => { wh.Wait(); // This is only null if we failed to create the subscription if (subscription != null) { subscription.Dispose(); } }); } catch (ObjectDisposedException) { // If we've ended the connection before we got a chance to register the connection // then dispose the subscription immediately disposeSubscriptionImmediately = true; } try { subscription = connection.Receive(LastMessageId, response => { // We need to wait until post receive has been called wh.Wait(); response.TimedOut = IsTimedOut; // If we're telling the client to disconnect then clean up the instantiated connection. if (response.Disconnect) { // Send the response before removing any connection data return(Send(response).Then(() => { // Remove connection without triggering disconnect HeartBeat.RemoveConnection(this); endRequest(null); // Dispose everything registration.Dispose(); subscription.Dispose(); return TaskAsyncHelper.False; })); } else if (response.TimedOut || response.Aborted || ConnectionEndToken.IsCancellationRequested) { if (response.Aborted) { // If this was a clean disconnect raise the event. OnDisconnect(); } endRequest(null); // Dispose everything registration.Dispose(); subscription.Dispose(); return(TaskAsyncHelper.False); } else { return(Send(response).Then(() => TaskAsyncHelper.True)); } }, MaxMessages); } catch (Exception ex) { endRequest(ex); wh.Set(); registration.Dispose(); return; } if (postReceive != null) { postReceive().Catch(_counters.ErrorsAllTotal, _counters.ErrorsAllPerSec) .Catch(ex => endRequest(ex)) .ContinueWith(task => wh.Set()); } else { wh.Set(); } if (disposeSubscriptionImmediately) { subscription.Dispose(); } }