@@ -48,10 +48,10 @@ internal partial class Channel : IChannel, IRecoverable
48
48
private bool _publisherConfirmationsEnabled = false ;
49
49
private bool _publisherConfirmationTrackingEnabled = false ;
50
50
private ushort ? _maxOutstandingPublisherConfirmations = null ;
51
+ private SemaphoreSlim ? _maxOutstandingConfirmationsSemaphore ;
51
52
private ulong _nextPublishSeqNo = 0 ;
52
53
private readonly SemaphoreSlim _confirmSemaphore = new ( 1 , 1 ) ;
53
54
private readonly ConcurrentDictionary < ulong , TaskCompletionSource < bool > > _confirmsTaskCompletionSources = new ( ) ;
54
- private readonly AsyncManualResetEvent _maxOutstandingPublisherConfirmsReached = new ( true ) ;
55
55
56
56
private class PublisherConfirmationInfo
57
57
{
@@ -124,6 +124,13 @@ private void ConfigurePublisherConfirmations(bool publisherConfirmationsEnabled,
124
124
_publisherConfirmationsEnabled = publisherConfirmationsEnabled ;
125
125
_publisherConfirmationTrackingEnabled = publisherConfirmationTrackingEnabled ;
126
126
_maxOutstandingPublisherConfirmations = maxOutstandingPublisherConfirmations ;
127
+
128
+ if ( _maxOutstandingPublisherConfirmations is not null )
129
+ {
130
+ _maxOutstandingConfirmationsSemaphore = new SemaphoreSlim (
131
+ ( int ) _maxOutstandingPublisherConfirmations ,
132
+ ( int ) _maxOutstandingPublisherConfirmations ) ;
133
+ }
127
134
}
128
135
129
136
private async Task MaybeConfirmSelect ( CancellationToken cancellationToken )
@@ -141,7 +148,6 @@ private async Task MaybeConfirmSelect(CancellationToken cancellationToken)
141
148
if ( _publisherConfirmationTrackingEnabled )
142
149
{
143
150
_confirmsTaskCompletionSources . Clear ( ) ;
144
- MaybeUnblockPublishers ( ) ;
145
151
}
146
152
_nextPublishSeqNo = 1 ;
147
153
}
@@ -187,15 +193,13 @@ private void HandleAck(ulong deliveryTag, bool multiple)
187
193
{
188
194
pair . Value . SetResult ( true ) ;
189
195
_confirmsTaskCompletionSources . Remove ( pair . Key , out _ ) ;
190
- MaybeUnblockPublishers ( ) ;
191
196
}
192
197
}
193
198
}
194
199
else
195
200
{
196
201
if ( _confirmsTaskCompletionSources . TryRemove ( deliveryTag , out TaskCompletionSource < bool > ? tcs ) )
197
202
{
198
- MaybeUnblockPublishers ( ) ;
199
203
tcs . SetResult ( true ) ;
200
204
}
201
205
}
@@ -215,15 +219,13 @@ private void HandleNack(ulong deliveryTag, bool multiple, bool isReturn)
215
219
{
216
220
pair . Value . SetException ( new PublishException ( pair . Key , isReturn ) ) ;
217
221
_confirmsTaskCompletionSources . Remove ( pair . Key , out _ ) ;
218
- MaybeUnblockPublishers ( ) ;
219
222
}
220
223
}
221
224
}
222
225
else
223
226
{
224
227
if ( _confirmsTaskCompletionSources . Remove ( deliveryTag , out TaskCompletionSource < bool > ? tcs ) )
225
228
{
226
- MaybeUnblockPublishers ( ) ;
227
229
tcs . SetException ( new PublishException ( deliveryTag , isReturn ) ) ;
228
230
}
229
231
}
@@ -266,7 +268,6 @@ await _confirmSemaphore.WaitAsync(reason.CancellationToken)
266
268
}
267
269
268
270
_confirmsTaskCompletionSources . Clear ( ) ;
269
- MaybeUnblockPublishers ( ) ;
270
271
}
271
272
}
272
273
finally
@@ -291,7 +292,12 @@ await _confirmSemaphore.WaitAsync(cancellationToken)
291
292
{
292
293
publisherConfirmationTcs = new TaskCompletionSource < bool > ( TaskCreationOptions . RunContinuationsAsynchronously ) ;
293
294
_confirmsTaskCompletionSources [ publishSequenceNumber ] = publisherConfirmationTcs ;
294
- MaybeBlockPublishers ( ) ;
295
+ }
296
+
297
+ if ( _maxOutstandingConfirmationsSemaphore is not null )
298
+ {
299
+ await _maxOutstandingConfirmationsSemaphore . WaitAsync ( cancellationToken )
300
+ . ConfigureAwait ( false ) ;
295
301
}
296
302
297
303
_nextPublishSeqNo ++ ;
@@ -318,7 +324,6 @@ private bool MaybeHandleExceptionWithEnabledPublisherConfirmations(PublisherConf
318
324
if ( _publisherConfirmationTrackingEnabled )
319
325
{
320
326
_confirmsTaskCompletionSources . TryRemove ( publisherConfirmationInfo . PublishSequenceNumber , out _ ) ;
321
- MaybeUnblockPublishers ( ) ;
322
327
}
323
328
324
329
exceptionWasHandled = publisherConfirmationInfo . MaybeHandleException ( ex ) ;
@@ -340,49 +345,10 @@ private async Task MaybeEndPublisherConfirmationTracking(PublisherConfirmationIn
340
345
await publisherConfirmationInfo . MaybeWaitForConfirmationAsync ( cancellationToken )
341
346
. ConfigureAwait ( false ) ;
342
347
}
343
- }
344
- }
345
-
346
- [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
347
- private ValueTask MaybeEnforceOutstandingPublisherConfirmationsAsync ( CancellationToken cancellationToken )
348
- {
349
- if ( _publisherConfirmationTrackingEnabled )
350
- {
351
- if ( _maxOutstandingPublisherConfirmsReached . IsSet )
352
- {
353
- return default ;
354
- }
355
- else
356
- {
357
- return _maxOutstandingPublisherConfirmsReached . WaitAsync ( cancellationToken ) ;
358
- }
359
- }
360
-
361
- return default ;
362
- }
363
-
364
- [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
365
- private void MaybeBlockPublishers ( )
366
- {
367
- if ( _publisherConfirmationTrackingEnabled )
368
- {
369
- if ( _maxOutstandingPublisherConfirmations is not null
370
- && _confirmsTaskCompletionSources . Count >= _maxOutstandingPublisherConfirmations )
371
- {
372
- _maxOutstandingPublisherConfirmsReached . Reset ( ) ;
373
- }
374
- }
375
- }
376
348
377
- [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
378
- private void MaybeUnblockPublishers ( )
379
- {
380
- if ( _publisherConfirmationTrackingEnabled )
381
- {
382
- if ( _maxOutstandingPublisherConfirmations is not null
383
- && _confirmsTaskCompletionSources . Count < _maxOutstandingPublisherConfirmations )
349
+ if ( _maxOutstandingConfirmationsSemaphore is not null )
384
350
{
385
- _maxOutstandingPublisherConfirmsReached . Set ( ) ;
351
+ _maxOutstandingConfirmationsSemaphore . Release ( ) ;
386
352
}
387
353
}
388
354
}
0 commit comments