@@ -91,6 +91,7 @@ type Options struct {
9191 // Maximum number of concurrent handlers. Defaults to 1.
9292 MaxHandlers int
9393 // Minimum size of a batch. Defaults to 1.
94+ // May be ignored during shutdown.
9495 MinBatchSize int
9596 // Maximum size of a batch. 0 means no limit.
9697 MaxBatchSize int
@@ -199,26 +200,33 @@ func (b *Batcher) AddNoWait(item any) <-chan error {
199200 b .pending = append (b .pending , waiter {item , c })
200201 if b .nHandlers < b .opts .MaxHandlers {
201202 // If we can start a handler, do so with the item just added and any others that are pending.
202- batch := b .nextBatch ()
203- if batch != nil {
204- b .wg .Add (1 )
205- go func () {
206- b .callHandler (batch )
207- b .wg .Done ()
208- }()
209- b .nHandlers ++
210- }
203+ b .handleBatch (b .nextBatch ())
211204 }
212205 // If we can't start a handler, then one of the currently running handlers will
213206 // take our item.
214207 return c
215208}
216209
210+ // Requires b.mu be held.
211+ func (b * Batcher ) handleBatch (batch []waiter ) {
212+ if len (batch ) == 0 {
213+ return
214+ }
215+ b .wg .Add (1 )
216+ go func () {
217+ b .callHandler (batch )
218+ b .wg .Done ()
219+ }()
220+ b .nHandlers ++
221+ }
222+
217223// nextBatch returns the batch to process, and updates b.pending.
218224// It returns nil if there's no batch ready for processing.
219225// b.mu must be held.
220226func (b * Batcher ) nextBatch () []waiter {
221- if len (b .pending ) < b .opts .MinBatchSize {
227+ // If we're not shutting down, respect minimums. If we're shutting down
228+ // though, we ignore minimums to make sure everything is flushed.
229+ if ! b .shutdown && len (b .pending ) < b .opts .MinBatchSize {
222230 return nil
223231 }
224232
@@ -282,6 +290,12 @@ func (b *Batcher) callHandler(batch []waiter) {
282290func (b * Batcher ) Shutdown () {
283291 b .mu .Lock ()
284292 b .shutdown = true
293+ // If there aren't any handlers running, there might be a partial
294+ // batch. Make sure it gets flushed even if it hasn't reached the
295+ // minimums.
296+ if b .nHandlers == 0 {
297+ b .handleBatch (b .nextBatch ())
298+ }
285299 b .mu .Unlock ()
286300 b .wg .Wait ()
287301}
0 commit comments