1package diodes 2 3import ( 4 "context" 5 "time" 6) 7 8// Diode is any implementation of a diode. 9type Diode interface { 10 Set(GenericDataType) 11 TryNext() (GenericDataType, bool) 12} 13 14// Poller will poll a diode until a value is available. 15type Poller struct { 16 Diode 17 interval time.Duration 18 ctx context.Context 19} 20 21// PollerConfigOption can be used to setup the poller. 22type PollerConfigOption func(*Poller) 23 24// WithPollingInterval sets the interval at which the diode is queried 25// for new data. The default is 10ms. 26func WithPollingInterval(interval time.Duration) PollerConfigOption { 27 return PollerConfigOption(func(c *Poller) { 28 c.interval = interval 29 }) 30} 31 32// WithPollingContext sets the context to cancel any retrieval (Next()). It 33// will not change any results for adding data (Set()). Default is 34// context.Background(). 35func WithPollingContext(ctx context.Context) PollerConfigOption { 36 return PollerConfigOption(func(c *Poller) { 37 c.ctx = ctx 38 }) 39} 40 41// NewPoller returns a new Poller that wraps the given diode. 42func NewPoller(d Diode, opts ...PollerConfigOption) *Poller { 43 p := &Poller{ 44 Diode: d, 45 interval: 10 * time.Millisecond, 46 ctx: context.Background(), 47 } 48 49 for _, o := range opts { 50 o(p) 51 } 52 53 return p 54} 55 56// Next polls the diode until data is available or until the context is done. 57// If the context is done, then nil will be returned. 58func (p *Poller) Next() GenericDataType { 59 for { 60 data, ok := p.Diode.TryNext() 61 if !ok { 62 if p.isDone() { 63 return nil 64 } 65 66 time.Sleep(p.interval) 67 continue 68 } 69 return data 70 } 71} 72 73func (p *Poller) isDone() bool { 74 select { 75 case <-p.ctx.Done(): 76 return true 77 default: 78 return false 79 } 80} 81