package timers import ( "context" "time" "github.com/nspcc-dev/neofs-node/pkg/morph/event" "github.com/pkg/errors" "go.uber.org/zap" ) type ( localTimer struct { duration time.Duration timer *time.Timer handler event.Handler } // Timers is a component for local inner ring timers to produce local events. Timers struct { log *zap.Logger epoch localTimer alphabet localTimer } // Params for timers instance constructor. Params struct { Log *zap.Logger EpochDuration time.Duration AlphabetDuration time.Duration } ) const ( // EpochTimer is a type for HandlerInfo structure. EpochTimer = "EpochTimer" // AlphabetTimer is a type for HandlerInfo structure. AlphabetTimer = "AlphabetTimer" ) // New creates instance of timers component. func New(p *Params) *Timers { return &Timers{ log: p.Log, epoch: localTimer{duration: p.EpochDuration}, alphabet: localTimer{duration: p.AlphabetDuration}, } } // Start runs all available local timers. func (t *Timers) Start(ctx context.Context) { t.epoch.timer = time.NewTimer(t.epoch.duration) t.alphabet.timer = time.NewTimer(t.alphabet.duration) go t.serve(ctx) } func (t *Timers) serve(ctx context.Context) { for { select { case <-ctx.Done(): t.log.Info("timers are getting stopped") t.epoch.timer.Stop() t.alphabet.timer.Stop() return case <-t.epoch.timer.C: // reset timer so it can tick once again t.epoch.timer.Reset(t.epoch.duration) // call handler, it should be always set t.epoch.handler(NewEpochTick{}) case <-t.alphabet.timer.C: // reset timer so it can tick once again t.alphabet.timer.Reset(t.alphabet.duration) // call handler, it should be always set t.alphabet.handler(NewAlphabetEmitTick{}) } } } // RegisterHandler of local timers events. func (t *Timers) RegisterHandler(h event.HandlerInfo) error { if h.Handler() == nil { return errors.New("ir/timers: can't register nil handler") } switch h.GetType() { case EpochTimer: t.epoch.handler = h.Handler() case AlphabetTimer: t.alphabet.handler = h.Handler() default: return errors.New("ir/timers: unknown handler type") } return nil }