1
+ using System ;
2
+ using System . Text ;
1
3
using System . Threading ;
4
+ using System . Threading . Tasks ;
2
5
using NUnit . Framework ;
3
6
using RabbitMQ . Client . Events ;
4
7
@@ -8,36 +11,54 @@ namespace RabbitMQ.Client.Unit
8
11
public class TestConsumer
9
12
{
10
13
[ Test ]
11
- public void TestBasicRoundtripConcurrent ( )
14
+ public async Task TestBasicRoundtripConcurrent ( )
12
15
{
13
- var cf = new ConnectionFactory { ProcessingConcurrency = 2 } ;
16
+ var cf = new ConnectionFactory { ProcessingConcurrency = 1 } ;
14
17
using ( IConnection c = cf . CreateConnection ( ) )
15
18
using ( IModel m = c . CreateModel ( ) )
16
19
{
17
20
QueueDeclareOk q = m . QueueDeclare ( ) ;
18
21
IBasicProperties bp = m . CreateBasicProperties ( ) ;
19
- var body = System . Text . Encoding . UTF8 . GetBytes ( "async-hi-1" ) ;
22
+ const string publish1 = "sync-hi-1" ;
23
+ var body = Encoding . UTF8 . GetBytes ( publish1 ) ;
20
24
m . BasicPublish ( "" , q . QueueName , bp , body ) ;
21
- body = System . Text . Encoding . UTF8 . GetBytes ( "async-hi-2" ) ;
25
+ const string publish2 = "sync-hi-2" ;
26
+ body = Encoding . UTF8 . GetBytes ( publish2 ) ;
22
27
m . BasicPublish ( "" , q . QueueName , bp , body ) ;
28
+
23
29
var consumer = new EventingBasicConsumer ( m ) ;
24
- var are = new CountdownEvent ( 2 ) ;
30
+
31
+ var publish1SyncSource = new TaskCompletionSource < bool > ( TaskCreationOptions . RunContinuationsAsynchronously ) ;
32
+ var publish2SyncSource = new TaskCompletionSource < bool > ( TaskCreationOptions . RunContinuationsAsynchronously ) ;
33
+ var maximumWaitTime = TimeSpan . FromSeconds ( 5 ) ;
34
+ var tokenSource = new CancellationTokenSource ( maximumWaitTime ) ;
35
+ tokenSource . Token . Register ( ( ) =>
36
+ {
37
+ publish1SyncSource . TrySetResult ( false ) ;
38
+ publish2SyncSource . TrySetResult ( false ) ;
39
+ } ) ;
40
+
25
41
consumer . Received += ( o , a ) =>
26
42
{
27
- Thread . Sleep ( 500 ) ;
28
- are . Signal ( ) ;
43
+ switch ( Encoding . UTF8 . GetString ( a . Body . ToArray ( ) ) )
44
+ {
45
+ case publish1 :
46
+ publish1SyncSource . TrySetResult ( true ) ;
47
+ publish2SyncSource . Task . GetAwaiter ( ) . GetResult ( ) ;
48
+ break ;
49
+ case publish2 :
50
+ publish2SyncSource . TrySetResult ( true ) ;
51
+ publish1SyncSource . Task . GetAwaiter ( ) . GetResult ( ) ;
52
+ break ;
53
+ }
29
54
} ;
30
- string tag = m . BasicConsume ( q . QueueName , true , consumer ) ;
31
- // ensure we get a delivery
32
- bool waitRes = are . Wait ( 800 ) ;
33
- Assert . IsTrue ( waitRes ) ;
34
55
35
- are . Reset ( 1 ) ;
36
- // unsubscribe and ensure no further deliveries
37
- m . BasicCancel ( tag ) ;
38
- m . BasicPublish ( "" , q . QueueName , bp , body ) ;
39
- bool waitResFalse = are . Wait ( 2000 ) ;
40
- Assert . IsFalse ( waitResFalse ) ;
56
+ m . BasicConsume ( q . QueueName , true , consumer ) ;
57
+
58
+ await Task . WhenAll ( publish1SyncSource . Task , publish2SyncSource . Task ) ;
59
+
60
+ Assert . IsTrue ( publish1SyncSource . Task . Result , $ "Non concurrent dispatch lead to deadlock after { maximumWaitTime } " ) ;
61
+ Assert . IsTrue ( publish2SyncSource . Task . Result , $ "Non concurrent dispatch lead to deadlock after { maximumWaitTime } " ) ;
41
62
}
42
63
}
43
64
}
0 commit comments