github.com/Jeffail/benthos/v3@v3.65.0/lib/output/writer/batched_send.go (about) 1 package writer 2 3 import ( 4 "errors" 5 6 "github.com/Jeffail/benthos/v3/internal/batch" 7 "github.com/Jeffail/benthos/v3/lib/types" 8 ) 9 10 // Returns true if the error should break a batch send loop. 11 func sendErrIsFatal(err error) bool { 12 if errors.Is(err, types.ErrTypeClosed) { 13 return true 14 } 15 if errors.Is(err, types.ErrNotConnected) { 16 return true 17 } 18 if errors.Is(err, types.ErrTimeout) { 19 return true 20 } 21 return false 22 } 23 24 // IterateBatchedSend executes a closure fn on each message of a batch, where 25 // the closure is expected to attempt a send and return an error. If an error is 26 // returned then it is added to a batch error in order to support index specific 27 // error handling. 28 // 29 // However, if a fatal error is returned such as a connection loss or shut down 30 // then it is returned immediately. 31 func IterateBatchedSend(msg types.Message, fn func(int, types.Part) error) error { 32 if msg.Len() == 1 { 33 return fn(0, msg.Get(0)) 34 } 35 var batchErr *batch.Error 36 if err := msg.Iter(func(i int, p types.Part) error { 37 tmpErr := fn(i, p) 38 if tmpErr != nil { 39 if sendErrIsFatal(tmpErr) { 40 return tmpErr 41 } 42 if batchErr == nil { 43 batchErr = batch.NewError(msg, tmpErr) 44 } 45 batchErr.Failed(i, tmpErr) 46 } 47 return nil 48 }); err != nil { 49 return err 50 } 51 if batchErr != nil { 52 return batchErr 53 } 54 return nil 55 }