6
6
using System . Buffers ;
7
7
using System . Collections . Generic ;
8
8
using System . Runtime . CompilerServices ;
9
+ using System . Threading ;
9
10
using System . Threading . Tasks ;
10
11
using Microsoft . Extensions . Logging ;
11
12
using Microsoft . Extensions . Logging . Abstractions ;
@@ -95,11 +96,14 @@ public class RawConsumer : AbstractEntity, IConsumer, IDisposable
95
96
private readonly RawConsumerConfig _config ;
96
97
private byte _subscriberId ;
97
98
private readonly ILogger _logger ;
99
+ private readonly CancellationTokenSource _cancelTokenSource = new ( ) ;
100
+ private readonly CancellationToken _token ;
98
101
99
102
private RawConsumer ( Client client , RawConsumerConfig config , ILogger logger = null )
100
103
{
101
104
_client = client ;
102
105
_config = config ;
106
+ _token = _cancelTokenSource . Token ;
103
107
_logger = logger ?? NullLogger . Instance ;
104
108
}
105
109
@@ -148,9 +152,14 @@ void DispatchMessage(ref SequenceReader<byte> sequenceReader, ulong i)
148
152
message . MessageOffset = chunk . ChunkId + i ;
149
153
if ( MaybeDispatch ( message . MessageOffset ) )
150
154
{
155
+ if ( _token . IsCancellationRequested )
156
+ {
157
+ return ;
158
+ }
159
+
151
160
_config . MessageHandler ( this ,
152
161
new MessageContext ( message . MessageOffset , TimeSpan . FromMilliseconds ( chunk . Timestamp ) ) ,
153
- message ) . GetAwaiter ( ) . GetResult ( ) ;
162
+ message ) . Wait ( _token ) ;
154
163
}
155
164
}
156
165
catch ( ArgumentOutOfRangeException e )
@@ -159,6 +168,12 @@ void DispatchMessage(ref SequenceReader<byte> sequenceReader, ulong i)
159
168
"Please report this issue to the RabbitMQ team on GitHub {Repo}" ,
160
169
Consts . RabbitMQClientRepo ) ;
161
170
}
171
+ catch ( OperationCanceledException )
172
+ {
173
+ _logger . LogWarning (
174
+ "OperationCanceledException. The consumer id: {SubscriberId} reference: {Reference} has been closed while consuming messages" ,
175
+ _subscriberId , _config . Reference ) ;
176
+ }
162
177
catch ( Exception e )
163
178
{
164
179
_logger . LogError ( e , "Error while processing chunk: {ChunkId}" , chunk . ChunkId ) ;
@@ -278,6 +293,8 @@ public async Task<ResponseCode> Close()
278
293
return ResponseCode . Ok ;
279
294
}
280
295
296
+ _cancelTokenSource . Cancel ( ) ;
297
+
281
298
var result = ResponseCode . Ok ;
282
299
try
283
300
{
@@ -299,12 +316,10 @@ public async Task<ResponseCode> Close()
299
316
300
317
var closed = _client . MaybeClose ( $ "_client-close-subscriber: { _subscriberId } ") ;
301
318
ClientExceptions . MaybeThrowException ( closed . ResponseCode , $ "_client-close-subscriber: { _subscriberId } ") ;
302
- _disposed = true ;
303
319
_logger . LogDebug ( "Consumer {SubscriberId} closed" , _subscriberId ) ;
304
320
return result ;
305
321
}
306
322
307
- //
308
323
private void Dispose ( bool disposing )
309
324
{
310
325
if ( ! disposing )
@@ -317,10 +332,18 @@ private void Dispose(bool disposing)
317
332
return ;
318
333
}
319
334
320
- var closeConsumer = Close ( ) ;
321
- closeConsumer . Wait ( TimeSpan . FromSeconds ( 1 ) ) ;
322
- ClientExceptions . MaybeThrowException ( closeConsumer . Result ,
323
- $ "Error during remove producer. Subscriber: { _subscriberId } ") ;
335
+ try
336
+ {
337
+ var closeConsumer = Close ( ) ;
338
+ closeConsumer . Wait ( TimeSpan . FromSeconds ( 1 ) ) ;
339
+ ClientExceptions . MaybeThrowException ( closeConsumer . Result ,
340
+ $ "Error during remove producer. Subscriber: { _subscriberId } ") ;
341
+ }
342
+ finally
343
+ {
344
+ _cancelTokenSource . Dispose ( ) ;
345
+ _disposed = true ;
346
+ }
324
347
}
325
348
326
349
public void Dispose ( )
@@ -333,8 +356,10 @@ public void Dispose()
333
356
{
334
357
_logger . LogError ( e , "Error during disposing of consumer: {SubscriberId}." , _subscriberId ) ;
335
358
}
336
-
337
- GC . SuppressFinalize ( this ) ;
359
+ finally
360
+ {
361
+ GC . SuppressFinalize ( this ) ;
362
+ }
338
363
}
339
364
}
340
365
}
0 commit comments