github.com/Jeffail/benthos/v3@v3.65.0/lib/input/reader/cut_off.go (about) 1 package reader 2 3 import ( 4 "time" 5 6 "github.com/Jeffail/benthos/v3/lib/types" 7 ) 8 9 //------------------------------------------------------------------------------ 10 11 // CutOff is a wrapper for reader.Type implementations that exits from 12 // WaitForClose immediately. This is only useful when the underlying readable 13 // resource cannot be closed reliably and can block forever. 14 type CutOff struct { 15 msgChan chan types.Message 16 errChan chan error 17 closeChan chan struct{} 18 19 r Type 20 } 21 22 // NewCutOff returns a new CutOff wrapper around a reader.Type. 23 func NewCutOff(r Type) *CutOff { 24 return &CutOff{ 25 msgChan: make(chan types.Message), 26 errChan: make(chan error), 27 closeChan: make(chan struct{}), 28 r: r, 29 } 30 } 31 32 //------------------------------------------------------------------------------ 33 34 // Connect attempts to establish a connection to the source, if unsuccessful 35 // returns an error. If the attempt is successful (or not necessary) returns 36 // nil. 37 func (c *CutOff) Connect() error { 38 return c.r.Connect() 39 } 40 41 // Acknowledge instructs whether messages read since the last Acknowledge call 42 // were successfully propagated. If the error is nil this will be forwarded to 43 // the underlying wrapped reader. If a non-nil error is returned the buffer of 44 // messages will be resent. 45 func (c *CutOff) Acknowledge(err error) error { 46 return c.r.Acknowledge(err) 47 } 48 49 // Read attempts to read a new message from the source. 50 func (c *CutOff) Read() (types.Message, error) { 51 go func() { 52 msg, err := c.r.Read() 53 if err == nil { 54 c.msgChan <- msg 55 } else { 56 c.errChan <- err 57 } 58 }() 59 select { 60 case m := <-c.msgChan: 61 return m, nil 62 case e := <-c.errChan: 63 return nil, e 64 case <-c.closeChan: 65 } 66 return nil, types.ErrTypeClosed 67 } 68 69 // CloseAsync triggers the asynchronous closing of the reader. 70 func (c *CutOff) CloseAsync() { 71 c.r.CloseAsync() 72 close(c.closeChan) 73 } 74 75 // WaitForClose blocks until either the reader is finished closing or a timeout 76 // occurs. 77 func (c *CutOff) WaitForClose(tout time.Duration) error { 78 return nil // We don't block here. 79 } 80 81 //------------------------------------------------------------------------------