@@ -43,6 +43,9 @@ namespace RabbitMQ.Client.Impl
43
43
{
44
44
internal abstract class AsyncRpcContinuation < T > : IRpcContinuation
45
45
{
46
+ private readonly TimeSpan _continuationTimeout ;
47
+ private readonly CancellationToken _rpcCancellationToken ;
48
+ private readonly CancellationToken _continuationTimeoutCancellationToken ;
46
49
private readonly CancellationTokenSource _continuationTimeoutCancellationTokenSource ;
47
50
private readonly CancellationTokenRegistration _continuationTimeoutCancellationTokenRegistration ;
48
51
private readonly CancellationTokenSource _linkedCancellationTokenSource ;
@@ -53,37 +56,25 @@ internal abstract class AsyncRpcContinuation<T> : IRpcContinuation
53
56
54
57
public AsyncRpcContinuation ( TimeSpan continuationTimeout , CancellationToken rpcCancellationToken )
55
58
{
59
+ _continuationTimeout = continuationTimeout ;
60
+ _rpcCancellationToken = rpcCancellationToken ;
61
+
56
62
/*
57
63
* Note: we can't use an ObjectPool for these because the netstandard2.0
58
64
* version of CancellationTokenSource can't be reset prior to checking
59
65
* in to the ObjectPool
60
66
*/
61
67
_continuationTimeoutCancellationTokenSource = new CancellationTokenSource ( continuationTimeout ) ;
68
+ _continuationTimeoutCancellationToken = _continuationTimeoutCancellationTokenSource . Token ;
62
69
63
70
#if NET
64
- _continuationTimeoutCancellationTokenRegistration = _continuationTimeoutCancellationTokenSource . Token . UnsafeRegister ( ( object ? state ) =>
65
- {
66
- var tcs = ( TaskCompletionSource < T > ) state ! ;
67
- if ( tcs . TrySetCanceled ( ) )
68
- {
69
- // Cancellation was successful, does this mean we set a TimeoutException
70
- // in the same manner as BlockingCell used to
71
- string msg = $ "operation '{ GetType ( ) . FullName } ' timed out after { continuationTimeout } ";
72
- tcs . TrySetException ( new TimeoutException ( msg ) ) ;
73
- }
74
- } , _tcs ) ;
71
+ _continuationTimeoutCancellationTokenRegistration =
72
+ _continuationTimeoutCancellationToken . UnsafeRegister (
73
+ callback : HandleContinuationTimeout , state : _tcs ) ;
75
74
#else
76
- _continuationTimeoutCancellationTokenRegistration = _continuationTimeoutCancellationTokenSource . Token . Register ( ( object state ) =>
77
- {
78
- var tcs = ( TaskCompletionSource < T > ) state ;
79
- if ( tcs . TrySetCanceled ( ) )
80
- {
81
- // Cancellation was successful, does this mean we set a TimeoutException
82
- // in the same manner as BlockingCell used to
83
- string msg = $ "operation '{ GetType ( ) . FullName } ' timed out after { continuationTimeout } ";
84
- tcs . TrySetException ( new TimeoutException ( msg ) ) ;
85
- }
86
- } , state : _tcs , useSynchronizationContext : false ) ;
75
+ _continuationTimeoutCancellationTokenRegistration =
76
+ _continuationTimeoutCancellationToken . Register (
77
+ callback : HandleContinuationTimeout , state : _tcs , useSynchronizationContext : false ) ;
87
78
#endif
88
79
89
80
_tcsConfiguredTaskAwaitable = _tcs . Task . ConfigureAwait ( false ) ;
@@ -114,9 +105,26 @@ await DoHandleCommandAsync(cmd)
114
105
}
115
106
catch ( OperationCanceledException )
116
107
{
117
- if ( CancellationToken . IsCancellationRequested )
108
+ if ( _rpcCancellationToken . IsCancellationRequested )
109
+ {
110
+ #if NET
111
+ _tcs . TrySetCanceled ( _rpcCancellationToken ) ;
112
+ #else
113
+ _tcs . TrySetCanceled ( ) ;
114
+ #endif
115
+ }
116
+ else if ( _continuationTimeoutCancellationToken . IsCancellationRequested )
118
117
{
119
- _tcs . SetCanceled ( ) ;
118
+ #if NET
119
+ if ( _tcs . TrySetCanceled ( _continuationTimeoutCancellationToken ) )
120
+ #else
121
+ if ( _tcs . TrySetCanceled ( ) )
122
+ #endif
123
+ {
124
+ // Cancellation was successful, does this mean we set a TimeoutException
125
+ // in the same manner as BlockingCell used to
126
+ _tcs . TrySetException ( GetTimeoutException ( ) ) ;
127
+ }
120
128
}
121
129
else
122
130
{
@@ -125,13 +133,24 @@ await DoHandleCommandAsync(cmd)
125
133
}
126
134
}
127
135
128
- protected abstract Task DoHandleCommandAsync ( IncomingCommand cmd ) ;
129
-
130
136
public virtual void HandleChannelShutdown ( ShutdownEventArgs reason )
131
137
{
132
138
_tcs . TrySetException ( new OperationInterruptedException ( reason ) ) ;
133
139
}
134
140
141
+ public void Dispose ( )
142
+ {
143
+ Dispose ( disposing : true ) ;
144
+ GC . SuppressFinalize ( this ) ;
145
+ }
146
+
147
+ protected abstract Task DoHandleCommandAsync ( IncomingCommand cmd ) ;
148
+
149
+ protected void HandleUnexpectedCommand ( IncomingCommand cmd )
150
+ {
151
+ _tcs . SetException ( new InvalidOperationException ( $ "Received unexpected command of type { cmd . CommandId } !") ) ;
152
+ }
153
+
135
154
protected virtual void Dispose ( bool disposing )
136
155
{
137
156
if ( ! _disposedValue )
@@ -147,10 +166,33 @@ protected virtual void Dispose(bool disposing)
147
166
}
148
167
}
149
168
150
- public void Dispose ( )
169
+ #if NET
170
+ private void HandleContinuationTimeout ( object ? state , CancellationToken cancellationToken )
151
171
{
152
- Dispose ( disposing : true ) ;
153
- GC . SuppressFinalize ( this ) ;
172
+ var tcs = ( TaskCompletionSource < T > ) state ! ;
173
+ if ( tcs . TrySetCanceled ( cancellationToken ) )
174
+ {
175
+ tcs . TrySetException ( GetTimeoutException ( ) ) ;
176
+ }
177
+ }
178
+ #else
179
+ private void HandleContinuationTimeout ( object state )
180
+ {
181
+ var tcs = ( TaskCompletionSource < T > ) state ;
182
+ if ( tcs . TrySetCanceled ( ) )
183
+ {
184
+ tcs . TrySetException ( GetTimeoutException ( ) ) ;
185
+ }
186
+ }
187
+ #endif
188
+
189
+ private TimeoutException GetTimeoutException ( )
190
+ {
191
+ // TODO
192
+ // Cancellation was successful, does this mean we set a TimeoutException
193
+ // in the same manner as BlockingCell used to
194
+ string msg = $ "operation '{ GetType ( ) . FullName } ' timed out after { _continuationTimeout } ";
195
+ return new TimeoutException ( msg ) ;
154
196
}
155
197
}
156
198
@@ -180,7 +222,7 @@ protected override Task DoHandleCommandAsync(IncomingCommand cmd)
180
222
}
181
223
else
182
224
{
183
- _tcs . SetException ( new InvalidOperationException ( $ "Received unexpected command of type { cmd . CommandId } !" ) ) ;
225
+ HandleUnexpectedCommand ( cmd ) ;
184
226
}
185
227
186
228
return Task . CompletedTask ;
@@ -206,7 +248,7 @@ protected override Task DoHandleCommandAsync(IncomingCommand cmd)
206
248
}
207
249
else
208
250
{
209
- _tcs . SetException ( new InvalidOperationException ( $ "Received unexpected command of type { cmd . CommandId } !" ) ) ;
251
+ HandleUnexpectedCommand ( cmd ) ;
210
252
}
211
253
212
254
return Task . CompletedTask ;
@@ -237,7 +279,7 @@ await _consumerDispatcher.HandleBasicCancelOkAsync(_consumerTag, CancellationTok
237
279
}
238
280
else
239
281
{
240
- _tcs . SetException ( new InvalidOperationException ( $ "Received unexpected command of type { cmd . CommandId } !" ) ) ;
282
+ HandleUnexpectedCommand ( cmd ) ;
241
283
}
242
284
}
243
285
}
@@ -268,7 +310,7 @@ await _consumerDispatcher.HandleBasicConsumeOkAsync(_consumer, method._consumerT
268
310
}
269
311
else
270
312
{
271
- _tcs . SetException ( new InvalidOperationException ( $ "Received unexpected command of type { cmd . CommandId } !" ) ) ;
313
+ HandleUnexpectedCommand ( cmd ) ;
272
314
}
273
315
}
274
316
}
@@ -310,7 +352,7 @@ protected override Task DoHandleCommandAsync(IncomingCommand cmd)
310
352
}
311
353
else
312
354
{
313
- _tcs . SetException ( new InvalidOperationException ( $ "Received unexpected command of type { cmd . CommandId } !" ) ) ;
355
+ HandleUnexpectedCommand ( cmd ) ;
314
356
}
315
357
316
358
return Task . CompletedTask ;
@@ -409,7 +451,7 @@ protected override Task DoHandleCommandAsync(IncomingCommand cmd)
409
451
}
410
452
else
411
453
{
412
- _tcs . SetException ( new InvalidOperationException ( $ "Received unexpected command of type { cmd . CommandId } !" ) ) ;
454
+ HandleUnexpectedCommand ( cmd ) ;
413
455
}
414
456
415
457
return Task . CompletedTask ;
@@ -448,7 +490,7 @@ protected override Task DoHandleCommandAsync(IncomingCommand cmd)
448
490
}
449
491
else
450
492
{
451
- _tcs . SetException ( new InvalidOperationException ( $ "Received unexpected command of type { cmd . CommandId } !" ) ) ;
493
+ HandleUnexpectedCommand ( cmd ) ;
452
494
}
453
495
454
496
return Task . CompletedTask ;
@@ -471,7 +513,7 @@ protected override Task DoHandleCommandAsync(IncomingCommand cmd)
471
513
}
472
514
else
473
515
{
474
- _tcs . SetException ( new InvalidOperationException ( $ "Received unexpected command of type { cmd . CommandId } !" ) ) ;
516
+ HandleUnexpectedCommand ( cmd ) ;
475
517
}
476
518
477
519
return Task . CompletedTask ;
0 commit comments