66using System . Buffers ;
77using System . Collections . Generic ;
88using System . Runtime . CompilerServices ;
9+ using System . Threading ;
910using System . Threading . Tasks ;
1011using Microsoft . Extensions . Logging ;
1112using Microsoft . Extensions . Logging . Abstractions ;
@@ -95,11 +96,14 @@ public class RawConsumer : AbstractEntity, IConsumer, IDisposable
9596 private readonly RawConsumerConfig _config ;
9697 private byte _subscriberId ;
9798 private readonly ILogger _logger ;
99+ private readonly CancellationTokenSource _cancelTokenSource = new ( ) ;
100+ private readonly CancellationToken _token ;
98101
99102 private RawConsumer ( Client client , RawConsumerConfig config , ILogger logger = null )
100103 {
101104 _client = client ;
102105 _config = config ;
106+ _token = _cancelTokenSource . Token ;
103107 _logger = logger ?? NullLogger . Instance ;
104108 }
105109
@@ -148,9 +152,14 @@ void DispatchMessage(ref SequenceReader<byte> sequenceReader, ulong i)
148152 message . MessageOffset = chunk . ChunkId + i ;
149153 if ( MaybeDispatch ( message . MessageOffset ) )
150154 {
155+ if ( _token . IsCancellationRequested )
156+ {
157+ return ;
158+ }
159+
151160 _config . MessageHandler ( this ,
152161 new MessageContext ( message . MessageOffset , TimeSpan . FromMilliseconds ( chunk . Timestamp ) ) ,
153- message ) . GetAwaiter ( ) . GetResult ( ) ;
162+ message ) . Wait ( _token ) ;
154163 }
155164 }
156165 catch ( ArgumentOutOfRangeException e )
@@ -159,6 +168,12 @@ void DispatchMessage(ref SequenceReader<byte> sequenceReader, ulong i)
159168 "Please report this issue to the RabbitMQ team on GitHub {Repo}" ,
160169 Consts . RabbitMQClientRepo ) ;
161170 }
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+ }
162177 catch ( Exception e )
163178 {
164179 _logger . LogError ( e , "Error while processing chunk: {ChunkId}" , chunk . ChunkId ) ;
@@ -278,6 +293,8 @@ public async Task<ResponseCode> Close()
278293 return ResponseCode . Ok ;
279294 }
280295
296+ _cancelTokenSource . Cancel ( ) ;
297+
281298 var result = ResponseCode . Ok ;
282299 try
283300 {
@@ -299,12 +316,10 @@ public async Task<ResponseCode> Close()
299316
300317 var closed = _client . MaybeClose ( $ "_client-close-subscriber: { _subscriberId } ") ;
301318 ClientExceptions . MaybeThrowException ( closed . ResponseCode , $ "_client-close-subscriber: { _subscriberId } ") ;
302- _disposed = true ;
303319 _logger . LogDebug ( "Consumer {SubscriberId} closed" , _subscriberId ) ;
304320 return result ;
305321 }
306322
307- //
308323 private void Dispose ( bool disposing )
309324 {
310325 if ( ! disposing )
@@ -317,10 +332,18 @@ private void Dispose(bool disposing)
317332 return ;
318333 }
319334
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+ }
324347 }
325348
326349 public void Dispose ( )
@@ -333,8 +356,10 @@ public void Dispose()
333356 {
334357 _logger . LogError ( e , "Error during disposing of consumer: {SubscriberId}." , _subscriberId ) ;
335358 }
336-
337- GC . SuppressFinalize ( this ) ;
359+ finally
360+ {
361+ GC . SuppressFinalize ( this ) ;
362+ }
338363 }
339364 }
340365}
0 commit comments