@@ -82,11 +82,13 @@ type Receiver struct {
82
82
83
83
Cfg ReceiverConfig
84
84
85
- log Logger
86
- mtx sync.Mutex
87
- receiver * azservicebus.Receiver
88
- options * azservicebus.ReceiverOptions
89
- handlers []Handler
85
+ log Logger
86
+ mtx sync.Mutex
87
+ receiver * azservicebus.Receiver
88
+ options * azservicebus.ReceiverOptions
89
+ handlers []Handler
90
+ serialHandler Handler
91
+ numberOfReceivedMessages int // for serial Handler only
90
92
}
91
93
92
94
type ReceiverOption func (* Receiver )
@@ -98,6 +100,14 @@ func WithHandlers(h ...Handler) ReceiverOption {
98
100
}
99
101
}
100
102
103
+ // WithSerialHandler
104
+ func WithSerialHandler (h Handler , n int ) ReceiverOption {
105
+ return func (r * Receiver ) {
106
+ r .serialHandler = h
107
+ r .numberOfReceivedMessages = n
108
+ }
109
+ }
110
+
101
111
// WithRenewalTime takes an optional time to renew the peek lock. This should be comfortably less
102
112
// than the peek lock timeout. For example: the default peek lock timeout is 60s and the default
103
113
// renewal time is 50s.
@@ -172,7 +182,7 @@ func (r *Receiver) processMessage(ctx context.Context, count int, maxDuration ti
172
182
173
183
r .log .Debugf ("Processing message %d" , count )
174
184
disp , ctx , err := r .handleReceivedMessageWithTracingContext (ctx , msg , handler )
175
- r .dispose (ctx , disp , err , msg )
185
+ r .Dispose (ctx , disp , err , msg )
176
186
177
187
duration := time .Since (now )
178
188
@@ -226,7 +236,7 @@ func (r *Receiver) renewMessageLock(ctx context.Context, count int, msg *Receive
226
236
}
227
237
}
228
238
229
- func (r * Receiver ) receiveMessages () error {
239
+ func (r * Receiver ) receiveMessagesInParallel () error {
230
240
231
241
numberOfReceivedMessages := len (r .handlers )
232
242
r .log .Debugf (
@@ -294,6 +304,55 @@ func (r *Receiver) receiveMessages() error {
294
304
}
295
305
}
296
306
307
+ func (r * Receiver ) receiveMessagesInSerial () error {
308
+
309
+ r .log .Debugf (
310
+ "NumberOfReceivedMessages %d, RenewMessageLock: %v" ,
311
+ r .numberOfReceivedMessages ,
312
+ r .Cfg .RenewMessageLock ,
313
+ )
314
+
315
+ ctx , cancel := context .WithCancel (context .Background ())
316
+ defer cancel ()
317
+ for {
318
+ var err error
319
+ var messages []* ReceivedMessage
320
+ messages , err = r .receiver .ReceiveMessages (ctx , r .numberOfReceivedMessages , nil )
321
+ if err != nil {
322
+ azerr := fmt .Errorf ("%s: ReceiveMessage failure: %w" , r , NewAzbusError (err ))
323
+ r .log .Infof ("%s" , azerr )
324
+ return azerr
325
+ }
326
+ total := len (messages )
327
+ r .log .Debugf ("total messages %d" , total )
328
+ var renewCtx context.Context
329
+ var renewCancel context.CancelFunc
330
+ var maxDuration time.Duration
331
+ // XXX: if the number of Received Messages is large (>10) then RenewMessageLock is required.
332
+ if r .Cfg .RenewMessageLock {
333
+ func () {
334
+ renewCtx , renewCancel = context .WithCancel (ctx )
335
+ defer renewCancel ()
336
+ for i , msg := range messages {
337
+ go r .renewMessageLock (renewCtx , i + 1 , msg )
338
+ }
339
+ for i , msg := range messages {
340
+ r .processMessage (renewCtx , i + 1 , maxDuration , msg , r .serialHandler )
341
+ }
342
+ }()
343
+ } else {
344
+ for i , msg := range messages {
345
+ func () {
346
+ // we need a timeout per message if RenewMessageLock is disabled
347
+ renewCtx , renewCancel , maxDuration = r .setTimeout (ctx , r .log , msg )
348
+ defer renewCancel ()
349
+ r .processMessage (renewCtx , i + 1 , maxDuration , msg , r .serialHandler )
350
+ }()
351
+ }
352
+ }
353
+ }
354
+ }
355
+
297
356
// The following 2 methods satisfy the startup.Listener interface.
298
357
func (r * Receiver ) Listen () error {
299
358
r .log .Debugf ("listen" )
@@ -303,21 +362,18 @@ func (r *Receiver) Listen() error {
303
362
r .log .Infof ("%s" , azerr )
304
363
return azerr
305
364
}
306
- return r .receiveMessages ()
365
+ if r .serialHandler != nil {
366
+ return r .receiveMessagesInSerial ()
367
+ }
368
+ return r .receiveMessagesInParallel ()
307
369
}
308
370
309
371
func (r * Receiver ) Shutdown (ctx context.Context ) error {
310
372
r .close_ ()
311
373
return nil
312
374
}
313
375
314
- func (r * Receiver ) open () error {
315
- var err error
316
-
317
- if r .receiver != nil {
318
- return nil
319
- }
320
-
376
+ func (r * Receiver ) openReceiver () error {
321
377
client , err := r .azClient .azClient ()
322
378
if err != nil {
323
379
return err
@@ -336,10 +392,27 @@ func (r *Receiver) open() error {
336
392
}
337
393
338
394
r .receiver = receiver
339
- for j := range len (r .handlers ) {
340
- err = r .handlers [j ].Open ()
341
- if err != nil {
342
- return fmt .Errorf ("failed to open handler: %w" , err )
395
+ return nil
396
+ }
397
+
398
+ func (r * Receiver ) open () error {
399
+ var err error
400
+
401
+ if r .receiver != nil {
402
+ return nil
403
+ }
404
+
405
+ err = r .openReceiver ()
406
+ if err != nil {
407
+ return err
408
+ }
409
+
410
+ if r .serialHandler == nil {
411
+ for j := range len (r .handlers ) {
412
+ err = r .handlers [j ].Open ()
413
+ if err != nil {
414
+ return fmt .Errorf ("failed to open handler: %w" , err )
415
+ }
343
416
}
344
417
}
345
418
return nil
0 commit comments