protected BatchedReadingReceiver(ILogger log, IReliableStateManager stateManager, PartitionReceiver receiver, IReliableDictionary <string, string> offsets, string partition, ServiceFabricRetryHandler retryHandler, Func <Exception, bool> transientExceptionChecker = null) : base(log, stateManager, receiver, offsets, partition, retryHandler, transientExceptionChecker) { }
protected BaseReadingReceiver(ILogger log, IReliableStateManager stateManager, PartitionReceiver receiver, IReliableDictionary <string, string> offsets, string partition, ServiceFabricRetryHandler retryHandler, Func <Exception, bool> transientExceptionChecker = null) { RetryHandler = retryHandler; Log = log; StateManager = stateManager; Receiver = receiver; _offsets = offsets; _partition = partition; TransientExceptionChecker = transientExceptionChecker; }
protected sealed override async Task RunAsync(CancellationToken cancellationToken) { var configuration = await TryConfigureAsync(cancellationToken).ConfigureAwait(false); try { var retryHandler = new ServiceFabricRetryHandler(cancellationToken); await InternalRunAsync(configuration, retryHandler).ConfigureAwait(false); } catch (Exception ex) { cancellationToken.ThrowIfCancellationRequested(); Log.Warning(ex, "Service failed but is not cancelled: {Exception}", ex.Message); await Task.Delay(5000, cancellationToken).ConfigureAwait(false); } }
private async Task InternalRunAsync(Configuration configuration, ServiceFabricRetryHandler retryHandler) { var tcs = new TaskCompletionSource <bool>(); using (retryHandler.ServiceCancellationToken.Register(() => { Log.Information("Service cancellation requested"); tcs.SetResult(true); })) { var tasks = new Task[configuration.Partitions.Length + 1]; for (var i = 0; i < configuration.Partitions.Length; i++) { tasks[i] = ProcessPartitionAsync(configuration.Partitions[i], configuration, retryHandler); } tasks[tasks.Length - 1] = WaitForCancellationAndClose(tcs.Task, configuration.Client); await Task.WhenAll(tasks).ConfigureAwait(false); } }
protected abstract Task <IReadingReceiver> CreateReadingReceiverAsync(ILogger log, IReliableStateManager stateManager, PartitionReceiver receiver, IReliableDictionary <string, string> offsets, string partition, ServiceFabricRetryHandler retryHandler);
private async Task ProcessPartitionAsync(string partition, Configuration configuration, ServiceFabricRetryHandler retryHandler) { var log = Log.ForContext("partition", partition); while (!retryHandler.IsCancellationRequested) { var offset = await retryHandler.CallAsync(_ => ReadOffsetAsync(partition, configuration.Offsets)).ConfigureAwait(false); Log.Information("Processing partition {Partition} from offset {Offset}", partition, offset); var receiver = CreateReceiver(log, configuration, partition, offset); try { using (var handler = await CreateReadingReceiverAsync(log, StateManager, receiver, configuration.Offsets, partition, retryHandler).ConfigureAwait(false)) { while (!retryHandler.IsCancellationRequested) { var messages = await receiver.ReceiveAsync(MaxEntries).ConfigureAwait(false); if (messages != null) { await handler.ProcessEventsAsync(messages).ConfigureAwait(false); } } } retryHandler.ThrowIfCancellationRequested(); } catch (Exception ex) { retryHandler.ThrowIfCancellationRequested(); log.Error(ex, "Error processing partition {Partition}: {Exception}", partition, ex.Message); } finally { log.Debug("Finished processing partition for {Partition}", partition); await receiver.CloseAsync().ConfigureAwait(false); } await retryHandler.RandomDelay().ConfigureAwait(false); } }