-
Notifications
You must be signed in to change notification settings - Fork 615
Description
Refer to the original issue for context #1014
Problem
When under load, stopping the AsyncConsumerWorkService can result in System.ObjectDisposedException being thrown due to a Disposed _limiter.
The Discarded Tasks HandleConcurrent started in LoopWithConcurrency may still be running after the finally block disposes of the _limiter Semaphore.
rabbitmq-dotnet-client/projects/RabbitMQ.Client/client/impl/AsyncConsumerWorkService.cs
Lines 125 to 151 in 4628927
| private async Task LoopWithConcurrency(CancellationToken cancellationToken) | |
| { | |
| try | |
| { | |
| while (await _channel.Reader.WaitToReadAsync(cancellationToken).ConfigureAwait(false)) | |
| { | |
| while (_channel.Reader.TryRead(out Work work)) | |
| { | |
| // Do a quick synchronous check before we resort to async/await with the state-machine overhead. | |
| if (!_limiter.Wait(0)) | |
| { | |
| await _limiter.WaitAsync(cancellationToken).ConfigureAwait(false); | |
| } | |
| _ = HandleConcurrent(work, _model, _limiter); | |
| } | |
| } | |
| } | |
| catch (OperationCanceledException) | |
| { | |
| // ignored | |
| } | |
| finally | |
| { | |
| _limiter?.Dispose(); | |
| } | |
| } |
When the HandleConcurrent Tasks attempt to Release the Semaphore, the System.ObjectDisposedException is thrown.
rabbitmq-dotnet-client/projects/RabbitMQ.Client/client/impl/AsyncConsumerWorkService.cs
Lines 181 to 186 in 4628927
| } | |
| finally | |
| { | |
| work.PostExecute(); | |
| limiter.Release(); | |
| } |
The issue doesn't occur in 6.2.2 but does in 6.2.3. It appears the PR #1113 might be the culprit.
Recommended Fix
- Release a patch version (possibly 6.2.4) with PR fix model shutdown event handler corner case #1113 reverted
- Release a patch version (possibly 6.2.4) with a fix applied to the 6.x branch
I'd be more than happy to submit a PR with a fix if that's the desired approach.