/// <summary> /// Process the next message for the subscription and return the subscription when successful. /// </summary> private async Task <Subscription> ProcessNextMessage(Subscription subscription, CancellationToken token) { bool processed = false; while (!processed) { token.ThrowIfCancellationRequested(); // Get the message from the transport byte[] msgBytes; try { msgBytes = await _transport.ReceiveMessage(subscription.Id, token).ConfigureAwait(false); } catch (OperationCanceledException) { throw; } catch (Exception e) { Logger.Error(e, "Error while receiving from transport for subscription {subscription}", subscription.Id); // Just start over with next message (TODO: Retry?) continue; } // Dispatch to handlers try { var dispatchTasks = subscription.Handlers.Select(h => h.Dispatch(_handlerFactory, msgBytes)); await Task.WhenAll(dispatchTasks).ConfigureAwait(false); } catch (Exception e) { Logger.Error(e, "Error while dispatching message to handlers for subscription {subscription}", subscription.Id); // Just go to next message (TODO: Handler retries?) continue; } processed = true; } return(subscription); }