@@ -59,12 +59,23 @@ public ErrorIngestion(
5959
6060 errorHandlingPolicy = new ErrorIngestionFaultPolicy ( dataStore , settings . LoggingSettings , OnCriticalError ) ;
6161
62- watchdog = new Watchdog ( "failed message ingestion" , EnsureStarted , EnsureStopped , ingestionState . ReportError , ingestionState . Clear , settings . TimeToRestartErrorIngestionAfterFailure , Logger ) ;
63-
64- ingestionWorker = Task . Run ( ( ) => Loop ( ) , CancellationToken . None ) ;
62+ watchdog = new Watchdog (
63+ "failed message ingestion" ,
64+ EnsureStarted ,
65+ EnsureStopped ,
66+ ingestionState . ReportError ,
67+ ingestionState . Clear ,
68+ settings . TimeToRestartErrorIngestionAfterFailure ,
69+ Logger
70+ ) ;
6571 }
6672
67- public Task StartAsync ( CancellationToken _ ) => watchdog . Start ( ( ) => applicationLifetime . StopApplication ( ) ) ;
73+ public async Task StartAsync ( CancellationToken cancellationToken )
74+ {
75+ stopSource = CancellationTokenSource . CreateLinkedTokenSource ( cancellationToken ) ;
76+ ingestionWorker = Task . Run ( ( ) => Loop ( stopSource . Token ) , stopSource . Token ) ;
77+ await watchdog . Start ( ( ) => applicationLifetime . StopApplication ( ) ) ;
78+ }
6879
6980 public async Task StopAsync ( CancellationToken cancellationToken )
7081 {
@@ -77,51 +88,54 @@ public async Task StopAsync(CancellationToken cancellationToken)
7788 }
7889 }
7990
80- async Task Loop ( )
91+ async Task Loop ( CancellationToken cancellationToken )
8192 {
82- var contexts = new List < MessageContext > ( transportSettings . MaxConcurrency . Value ) ;
83-
84- while ( await channel . Reader . WaitToReadAsync ( ) )
93+ try
8594 {
86- // will only enter here if there is something to read.
87- try
95+ var contexts = new List < MessageContext > ( transportSettings . MaxConcurrency . Value ) ;
96+
97+ while ( await channel . Reader . WaitToReadAsync ( cancellationToken ) )
8898 {
89- // as long as there is something to read this will fetch up to MaximumConcurrency items
90- while ( channel . Reader . TryRead ( out var context ) )
99+ // will only enter here if there is something to read.
100+ try
91101 {
92- contexts . Add ( context ) ;
102+ // as long as there is something to read this will fetch up to MaximumConcurrency items
103+ while ( channel . Reader . TryRead ( out var context ) )
104+ {
105+ contexts . Add ( context ) ;
106+ }
107+
108+ batchSizeMeter . Mark ( contexts . Count ) ;
109+ using ( batchDurationMeter . Measure ( ) )
110+ {
111+ await ingestor . Ingest ( contexts ) ;
112+ }
93113 }
94-
95- batchSizeMeter . Mark ( contexts . Count ) ;
96- using ( batchDurationMeter . Measure ( ) )
114+ catch ( OperationCanceledException ) when ( cancellationToken . IsCancellationRequested )
97115 {
98- await ingestor . Ingest ( contexts ) ;
116+ throw ; // Catch again in outer catch
99117 }
100- }
101- catch ( OperationCanceledException )
102- {
103- //Do nothing as we are shutting down
104- continue ;
105- }
106- catch ( Exception e ) // show must go on
107- {
108- if ( Logger . IsInfoEnabled )
118+ catch ( Exception e ) // show must go on
109119 {
110120 Logger . Info ( "Ingesting messages failed" , e ) ;
111- }
112121
113- // signal all message handling tasks to terminate
114- foreach ( var context in contexts )
122+ // signal all message handling tasks to terminate
123+ foreach ( var context in contexts )
124+ {
125+ context . GetTaskCompletionSource ( ) . TrySetException ( e ) ;
126+ }
127+ }
128+ finally
115129 {
116- context . GetTaskCompletionSource ( ) . TrySetException ( e ) ;
130+ contexts . Clear ( ) ;
117131 }
118132 }
119- finally
120- {
121- contexts . Clear ( ) ;
122- }
133+ // will fall out here when writer is completed
134+ }
135+ catch ( OperationCanceledException ) when ( cancellationToken . IsCancellationRequested )
136+ {
137+ // Cancellation
123138 }
124- // will fall out here when writer is completed
125139 }
126140
127141 async Task EnsureStarted ( CancellationToken cancellationToken = default )
@@ -230,19 +244,21 @@ async Task EnsureStopped(CancellationToken cancellationToken = default)
230244 ErrorIngestionFaultPolicy errorHandlingPolicy ;
231245 TransportInfrastructure transportInfrastructure ;
232246 IMessageReceiver messageReceiver ;
247+ Task ingestionWorker ;
248+ CancellationTokenSource stopSource ;
233249
234250 readonly Settings settings ;
235251 readonly ITransportCustomization transportCustomization ;
236252 readonly TransportSettings transportSettings ;
237253 readonly Watchdog watchdog ;
238254 readonly Channel < MessageContext > channel ;
239- readonly Task ingestionWorker ;
240255 readonly Meter batchDurationMeter ;
241256 readonly Meter batchSizeMeter ;
242257 readonly Counter receivedMeter ;
243258 readonly ErrorIngestor ingestor ;
244259 readonly IIngestionUnitOfWorkFactory unitOfWorkFactory ;
245260 readonly IHostApplicationLifetime applicationLifetime ;
261+
246262 static readonly ILog Logger = LogManager . GetLogger < ErrorIngestion > ( ) ;
247263 }
248264}
0 commit comments