1+ using System ;
2+ using System . Text ;
13using System . Threading ;
4+ using System . Threading . Tasks ;
25using NUnit . Framework ;
36using RabbitMQ . Client . Events ;
47
@@ -8,36 +11,54 @@ namespace RabbitMQ.Client.Unit
811 public class TestConsumer
912 {
1013 [ Test ]
11- public void TestBasicRoundtripConcurrent ( )
14+ public async Task TestBasicRoundtripConcurrent ( )
1215 {
13- var cf = new ConnectionFactory { ProcessingConcurrency = 2 } ;
16+ var cf = new ConnectionFactory { ProcessingConcurrency = 1 } ;
1417 using ( IConnection c = cf . CreateConnection ( ) )
1518 using ( IModel m = c . CreateModel ( ) )
1619 {
1720 QueueDeclareOk q = m . QueueDeclare ( ) ;
1821 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 ) ;
2024 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 ) ;
2227 m . BasicPublish ( "" , q . QueueName , bp , body ) ;
28+
2329 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+
2541 consumer . Received += ( o , a ) =>
2642 {
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+ }
2954 } ;
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 ) ;
3455
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 } " ) ;
4162 }
4263 }
4364 }
0 commit comments