protected sealed override async Task OnInitializingPartitionAsync(EventProcessorPartition partition, CancellationToken cancellationToken) { _partitionInitializeProcessing.Increment(); using (_logger.BeginScope("Processor Initialization")) { _logger.LogInformation("Processing initialization received on partition {partitionId}", partition.PartitionId); if (!_partitionContexts.TryGetValue(partition.PartitionId, out var context)) { context = new ProcessorPartitionContext(_logger, _metricFactory, partition.PartitionId, () => ReadLastEnqueuedEventProperties(partition.PartitionId), _checkpointManager); _partitionContexts.TryAdd(partition.PartitionId, context); } if (!_partitionProcessors.TryGetValue(partition.PartitionId, out var processor)) { if (_partitionContexts.TryGetValue(partition.PartitionId, out var partitionContext)) { processor = CreateProcessor(_logger, _metricFactory, partitionContext); await processor.InitializeAsync(_logger, _metricFactory, partitionContext).ConfigureAwait(false); _partitionProcessors.TryAdd(partition.PartitionId, processor); } else { _logger.LogError("Error retrieving context from context list for partition {partitionId}", partition.PartitionId); throw new ApplicationException($"Error retriving partition from list for partition {partition.PartitionId}"); } } await processor.PartitionInitializeAsync(context, cancellationToken).ConfigureAwait(false); } }
protected abstract Task ProcessBatchAsync(IEnumerable <EventData> events, IProcessor processor, ProcessorPartitionContext partitionContext, CancellationToken cancellationToken);
protected abstract IProcessor CreateProcessor(ILogger logger, IMetricFactory metricFactory, ProcessorPartitionContext partitionContext);
/// <inheritdoc /> protected sealed override async Task ProcessBatchAsync(IEnumerable <EventData> events, IProcessor processor, ProcessorPartitionContext partitionContext, CancellationToken cancellationToken) { Dictionary <long, Exception> exceptions = null; var eventFound = false; var processorInstance = processor as IEventProcessor; try { if (events == null) { foreach (var eventData in events) { eventFound = true; try { await processorInstance.PartitionProcessAsync(eventData, partitionContext, cancellationToken).ConfigureAwait(false); } catch (Exception e) when(!(e is TaskCanceledException)) { exceptions ??= new Dictionary <long, Exception>(); exceptions.Add(eventData.SequenceNumber, e); } } } if (!eventFound) { try { await processorInstance.PartitionProcessAsync(null, partitionContext, cancellationToken).ConfigureAwait(false); } catch (Exception e) when(!(e is TaskCanceledException)) { exceptions ??= new Dictionary <long, Exception>(); exceptions.Add(-1, e); } } } catch (Exception e) when(!(e is TaskCanceledException)) { _logger.LogError(e, "An error caught in the batch that was not a cancellation exception"); throw; } finally { _logger.LogDebug("Completed batch processing"); } var exceptionCount = (exceptions?.Count ?? 0); if (exceptionCount > 0) { if (exceptionCount == 1) { ExceptionDispatchInfo.Capture(exceptions[0]).Throw(); } throw new HubProcessingException($"Error processing messages in batch on partition {partitionContext.PartitionId}", exceptions); } }
/// <inheritdoc /> protected sealed override IProcessor CreateProcessor(ILogger logger, IMetricFactory metricFactory, ProcessorPartitionContext partitionContext) { return(_processorFactory(logger, metricFactory, partitionContext)); }
/// <inheritdoc /> protected sealed override async Task ProcessBatchAsync(IEnumerable <EventData> events, IProcessor processor, ProcessorPartitionContext partitionContext, CancellationToken cancellationToken) { var processorInstance = processor as IEventBatchProcessor; try { await processorInstance.PartitionProcessAsync(events, partitionContext, cancellationToken).ConfigureAwait(false); } catch (Exception e) when(!(e is TaskCanceledException)) { _logger.LogError(e, "An error caught in the batch that was not a cancellation exception"); throw; } finally { _logger.LogDebug("Completed batch processing"); } }