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  //------------------------------------------------------------------------------