38
38
using System . Threading . Tasks ;
39
39
using RabbitMQ . Client ;
40
40
41
- // const int MESSAGE_COUNT = 50_000;
42
- const int MESSAGE_COUNT = 5 ;
41
+ const int MESSAGE_COUNT = 50_000 ;
43
42
bool debug = false ;
44
43
45
44
#pragma warning disable CS8321 // Local function is declared but never used
46
45
47
- // await PublishMessagesIndividuallyAsync();
48
- // await PublishMessagesInBatchAsync();
46
+ await PublishMessagesIndividuallyAsync ( ) ;
47
+ await PublishMessagesInBatchAsync ( ) ;
49
48
await HandlePublishConfirmsAsynchronously ( ) ;
50
49
51
50
static Task < IConnection > CreateConnectionAsync ( )
@@ -68,10 +67,15 @@ static async Task PublishMessagesIndividuallyAsync()
68
67
var sw = new Stopwatch ( ) ;
69
68
sw . Start ( ) ;
70
69
70
+ bool ack = false ;
71
71
for ( int i = 0 ; i < MESSAGE_COUNT ; i ++ )
72
72
{
73
73
byte [ ] body = Encoding . UTF8 . GetBytes ( i . ToString ( ) ) ;
74
- await channel . BasicPublishAsync ( exchange : string . Empty , routingKey : queueName , body : body ) ;
74
+ ack = await channel . BasicPublishAsync ( exchange : string . Empty , routingKey : queueName , body : body ) ;
75
+ if ( false == ack )
76
+ {
77
+ Console . Error . WriteLine ( $ "{ DateTime . Now } [ERROR] saw nack '{ ack } '") ;
78
+ }
75
79
}
76
80
77
81
sw . Stop ( ) ;
@@ -90,7 +94,7 @@ static async Task PublishMessagesInBatchAsync()
90
94
QueueDeclareOk queueDeclareResult = await channel . QueueDeclareAsync ( ) ;
91
95
string queueName = queueDeclareResult . QueueName ;
92
96
93
- int batchSize = 500 ;
97
+ int batchSize = 1000 ;
94
98
int outstandingMessageCount = 0 ;
95
99
96
100
var sw = new Stopwatch ( ) ;
@@ -105,9 +109,13 @@ static async Task PublishMessagesInBatchAsync()
105
109
106
110
if ( outstandingMessageCount == batchSize )
107
111
{
108
- foreach ( ValueTask < bool > vt in publishTasks )
112
+ foreach ( ValueTask < bool > pt in publishTasks )
109
113
{
110
- await vt ;
114
+ bool ack = await pt ;
115
+ if ( false == ack )
116
+ {
117
+ Console . Error . WriteLine ( $ "{ DateTime . Now } [ERROR] saw nack '{ ack } '") ;
118
+ }
111
119
}
112
120
publishTasks . Clear ( ) ;
113
121
outstandingMessageCount = 0 ;
@@ -116,9 +124,13 @@ static async Task PublishMessagesInBatchAsync()
116
124
117
125
if ( publishTasks . Count > 0 )
118
126
{
119
- foreach ( ValueTask < bool > vt in publishTasks )
127
+ foreach ( ValueTask < bool > pt in publishTasks )
120
128
{
121
- await vt ;
129
+ bool ack = await pt ;
130
+ if ( false == ack )
131
+ {
132
+ Console . Error . WriteLine ( $ "{ DateTime . Now } [ERROR] saw nack '{ ack } '") ;
133
+ }
122
134
}
123
135
publishTasks . Clear ( ) ;
124
136
outstandingMessageCount = 0 ;
@@ -134,25 +146,21 @@ async Task HandlePublishConfirmsAsynchronously()
134
146
135
147
await using IConnection connection = await CreateConnectionAsync ( ) ;
136
148
137
- // NOTE: setting trackConfirmations to false because this program
138
- // is tracking them itself.
139
149
var channelOptions = new CreateChannelOptions
140
150
{
141
151
PublisherConfirmationsEnabled = true ,
142
- PublisherConfirmationTrackingEnabled = true
152
+ PublisherConfirmationTrackingEnabled = false
143
153
} ;
144
154
await using IChannel channel = await connection . CreateChannelAsync ( channelOptions ) ;
145
155
146
156
// declare a server-named queue
147
157
QueueDeclareOk queueDeclareResult = await channel . QueueDeclareAsync ( ) ;
148
158
string queueName = queueDeclareResult . QueueName ;
149
159
150
- #pragma warning disable CS0219 // Variable is assigned but its value is never used
151
- bool publishingCompleted = false ;
152
- #pragma warning restore CS0219 // Variable is assigned but its value is never used
153
160
var allMessagesConfirmedTcs = new TaskCompletionSource < bool > ( TaskCreationOptions . RunContinuationsAsynchronously ) ;
154
161
var outstandingConfirms = new LinkedList < ulong > ( ) ;
155
162
var semaphore = new SemaphoreSlim ( 1 , 1 ) ;
163
+ int confirmedCount = 0 ;
156
164
async Task CleanOutstandingConfirms ( ulong deliveryTag , bool multiple )
157
165
{
158
166
if ( debug )
@@ -181,10 +189,13 @@ async Task CleanOutstandingConfirms(ulong deliveryTag, bool multiple)
181
189
{
182
190
break ;
183
191
}
192
+
193
+ confirmedCount ++ ;
184
194
} while ( true ) ;
185
195
}
186
196
else
187
197
{
198
+ confirmedCount ++ ;
188
199
outstandingConfirms . Remove ( deliveryTag ) ;
189
200
}
190
201
}
@@ -193,8 +204,7 @@ async Task CleanOutstandingConfirms(ulong deliveryTag, bool multiple)
193
204
semaphore . Release ( ) ;
194
205
}
195
206
196
- // if (publishingCompleted && outstandingConfirms.Count == 0)
197
- if ( outstandingConfirms . Count == 0 )
207
+ if ( outstandingConfirms . Count == 0 || confirmedCount == MESSAGE_COUNT )
198
208
{
199
209
allMessagesConfirmedTcs . SetResult ( true ) ;
200
210
}
@@ -248,8 +258,12 @@ async Task CleanOutstandingConfirms(ulong deliveryTag, bool multiple)
248
258
semaphore . Release ( ) ;
249
259
}
250
260
251
- // string rk = queueName;
252
- string rk = Guid . NewGuid ( ) . ToString ( ) ;
261
+ string rk = queueName ;
262
+ if ( i % 1000 == 0 )
263
+ {
264
+ // This will cause a basic.return, for fun
265
+ rk = Guid . NewGuid ( ) . ToString ( ) ;
266
+ }
253
267
ValueTask < bool > pt = channel . BasicPublishAsync ( exchange : string . Empty , routingKey : rk , body : body , mandatory : true ) ;
254
268
publishTasks . Add ( pt ) ;
255
269
}
@@ -259,9 +273,11 @@ async Task CleanOutstandingConfirms(ulong deliveryTag, bool multiple)
259
273
foreach ( ValueTask < bool > pt in publishTasks )
260
274
{
261
275
bool ack = await pt ;
262
- Console . WriteLine ( $ "{ DateTime . Now } [INFO] saw ack '{ ack } '") ;
276
+ if ( false == ack )
277
+ {
278
+ Console . Error . WriteLine ( $ "{ DateTime . Now } [ERROR] saw nack '{ ack } '") ;
279
+ }
263
280
}
264
- publishingCompleted = true ;
265
281
266
282
try
267
283
{
0 commit comments