frostfs-node/modules/workers/prepare.go
alexvanin dadfd90dcd Initial commit
Initial public review release v0.10.0
2020-07-10 17:45:00 +03:00

132 lines
2.2 KiB
Go

package workers
import (
"context"
"time"
"github.com/nspcc-dev/neofs-node/lib/fix/worker"
"github.com/spf13/viper"
"go.uber.org/dig"
"go.uber.org/zap"
)
type (
// Result returns wrapped workers group for DI.
Result struct {
dig.Out
Workers []*worker.Job
}
// Params is dependencies for create workers slice.
Params struct {
dig.In
Jobs worker.Jobs
Viper *viper.Viper
Logger *zap.Logger
}
)
func prepare(p Params) worker.Workers {
w := worker.New()
for name, handler := range p.Jobs {
if job := byConfig(name, handler, p.Logger, p.Viper); job != nil {
p.Logger.Debug("worker: add new job",
zap.String("name", name))
w.Add(job)
}
}
return w
}
func byTicker(d time.Duration, h worker.Handler) worker.Handler {
return func(ctx context.Context) {
ticker := time.NewTicker(d)
defer ticker.Stop()
for {
select {
case <-ctx.Done():
return
default:
select {
case <-ctx.Done():
return
case <-ticker.C:
h(ctx)
}
}
}
}
}
func byTimer(d time.Duration, h worker.Handler) worker.Handler {
return func(ctx context.Context) {
timer := time.NewTimer(d)
defer timer.Stop()
for {
select {
case <-ctx.Done():
return
default:
select {
case <-ctx.Done():
return
case <-timer.C:
h(ctx)
timer.Reset(d)
}
}
}
}
}
func byConfig(name string, h worker.Handler, l *zap.Logger, v *viper.Viper) worker.Handler {
var job worker.Handler
if !v.IsSet("workers." + name) {
l.Info("worker: has no configuration",
zap.String("worker", name))
return nil
}
if v.GetBool("workers." + name + ".disabled") {
l.Info("worker: disabled",
zap.String("worker", name))
return nil
}
if ticker := v.GetDuration("workers." + name + ".ticker"); ticker > 0 {
job = byTicker(ticker, h)
}
if timer := v.GetDuration("workers." + name + ".timer"); timer > 0 {
job = byTimer(timer, h)
}
if v.GetBool("workers." + name + ".immediately") {
return func(ctx context.Context) {
h(ctx)
if job == nil {
return
}
// check context before run immediately job again
select {
case <-ctx.Done():
return
default:
}
job(ctx)
}
}
return job
}