github.com/Jeffail/benthos/v3@v3.65.0/internal/batch/combined_ack_func.go (about)

     1  package batch
     2  
     3  import (
     4  	"context"
     5  	"sync"
     6  )
     7  
     8  // AckFunc is a common function signature for acknowledging receipt of messages.
     9  type AckFunc func(context.Context, error) error
    10  
    11  // CombinedAcker creates a single ack func closure that aggregates one or more
    12  // derived closures such that only once each derived closure is called the
    13  // singular ack func will trigger. If at least one derived closure receives an
    14  // error the singular ack func will send the first non-nil error received.
    15  type CombinedAcker struct {
    16  	mut           sync.Mutex
    17  	remainingAcks int
    18  	err           error
    19  	root          AckFunc
    20  }
    21  
    22  // NewCombinedAcker creates an aggregated that derives one or more ack funcs
    23  // that, once all of which have been called, the provided root ack func is
    24  // called.
    25  func NewCombinedAcker(aFn AckFunc) *CombinedAcker {
    26  	return &CombinedAcker{
    27  		remainingAcks: 0,
    28  		root:          aFn,
    29  	}
    30  }
    31  
    32  // Derive creates a new ack func that must be called before the origin ack func
    33  // will be called. It is invalid to derive an ack func after any other
    34  // previously derived funcs have been called.
    35  func (c *CombinedAcker) Derive() AckFunc {
    36  	c.mut.Lock()
    37  	c.remainingAcks++
    38  	c.mut.Unlock()
    39  
    40  	var decrementOnce sync.Once
    41  	return func(ctx context.Context, ackErr error) (err error) {
    42  		decrementOnce.Do(func() {
    43  			c.mut.Lock()
    44  			c.remainingAcks--
    45  			remaining := c.remainingAcks
    46  			if ackErr != nil {
    47  				c.err = ackErr
    48  			}
    49  			ackErr = c.err
    50  			c.mut.Unlock()
    51  			if remaining == 0 {
    52  				err = c.root(ctx, ackErr)
    53  			}
    54  		})
    55  		return
    56  	}
    57  }