github.com/Jeffail/benthos/v3@v3.65.0/lib/processor/sleep.go (about) 1 package processor 2 3 import ( 4 "fmt" 5 "sync/atomic" 6 "time" 7 8 "github.com/Jeffail/benthos/v3/internal/bloblang/field" 9 "github.com/Jeffail/benthos/v3/internal/docs" 10 "github.com/Jeffail/benthos/v3/internal/interop" 11 "github.com/Jeffail/benthos/v3/internal/tracing" 12 "github.com/Jeffail/benthos/v3/lib/log" 13 "github.com/Jeffail/benthos/v3/lib/metrics" 14 "github.com/Jeffail/benthos/v3/lib/types" 15 ) 16 17 //------------------------------------------------------------------------------ 18 19 func init() { 20 Constructors[TypeSleep] = TypeSpec{ 21 constructor: NewSleep, 22 Categories: []Category{ 23 CategoryUtility, 24 }, 25 Summary: ` 26 Sleep for a period of time specified as a duration string. This processor will 27 interpolate functions within the ` + "`duration`" + ` field, you can find a list 28 of functions [here](/docs/configuration/interpolation#bloblang-queries).`, 29 Description: ` 30 This processor executes once per message batch. In order to execute once for 31 each message of a batch place it within a 32 ` + "[`for_each`](/docs/components/processors/for_each)" + ` processor: 33 34 ` + "```yaml" + ` 35 pipeline: 36 processors: 37 - for_each: 38 - sleep: 39 duration: ${! meta("sleep_for") } 40 ` + "```" + ``, 41 FieldSpecs: docs.FieldSpecs{ 42 docs.FieldInterpolatedString("duration", "The duration of time to sleep for each execution."), 43 }, 44 } 45 } 46 47 //------------------------------------------------------------------------------ 48 49 // SleepConfig contains configuration fields for the Sleep processor. 50 type SleepConfig struct { 51 Duration string `json:"duration" yaml:"duration"` 52 } 53 54 // NewSleepConfig returns a SleepConfig with default values. 55 func NewSleepConfig() SleepConfig { 56 return SleepConfig{ 57 Duration: "100us", 58 } 59 } 60 61 //------------------------------------------------------------------------------ 62 63 // Sleep is a processor that limits the stream of a pipeline to one message 64 // batch per period specified. 65 type Sleep struct { 66 closed int32 67 closeChan chan struct{} 68 69 conf Config 70 log log.Modular 71 stats metrics.Type 72 73 durationStr *field.Expression 74 75 mCount metrics.StatCounter 76 mErr metrics.StatCounter 77 mSent metrics.StatCounter 78 mBatchSent metrics.StatCounter 79 } 80 81 // NewSleep returns a Sleep processor. 82 func NewSleep( 83 conf Config, mgr types.Manager, log log.Modular, stats metrics.Type, 84 ) (Type, error) { 85 durationStr, err := interop.NewBloblangField(mgr, conf.Sleep.Duration) 86 if err != nil { 87 return nil, fmt.Errorf("failed to parse duration expression: %v", err) 88 } 89 t := &Sleep{ 90 closeChan: make(chan struct{}), 91 conf: conf, 92 log: log, 93 stats: stats, 94 95 durationStr: durationStr, 96 97 mCount: stats.GetCounter("count"), 98 mErr: stats.GetCounter("error"), 99 mSent: stats.GetCounter("sent"), 100 mBatchSent: stats.GetCounter("batch.sent"), 101 } 102 return t, nil 103 } 104 105 //------------------------------------------------------------------------------ 106 107 // ProcessMessage applies the processor to a message, either creating >0 108 // resulting messages or a response to be sent back to the message source. 109 func (s *Sleep) ProcessMessage(msg types.Message) ([]types.Message, types.Response) { 110 s.mCount.Incr(1) 111 112 spans := tracing.CreateChildSpans(TypeSleep, msg) 113 defer func() { 114 for _, span := range spans { 115 span.Finish() 116 } 117 }() 118 119 period, err := time.ParseDuration(s.durationStr.String(0, msg)) 120 if err != nil { 121 s.log.Errorf("Failed to parse duration: %v\n", err) 122 s.mErr.Incr(1) 123 } 124 select { 125 case <-time.After(period): 126 case <-s.closeChan: 127 } 128 129 s.mBatchSent.Incr(1) 130 s.mSent.Incr(int64(msg.Len())) 131 msgs := [1]types.Message{msg} 132 return msgs[:], nil 133 } 134 135 // CloseAsync shuts down the processor and stops processing requests. 136 func (s *Sleep) CloseAsync() { 137 if atomic.CompareAndSwapInt32(&s.closed, 0, 1) { 138 close(s.closeChan) 139 } 140 } 141 142 // WaitForClose blocks until the processor has closed down. 143 func (s *Sleep) WaitForClose(timeout time.Duration) error { 144 return nil 145 } 146 147 //------------------------------------------------------------------------------