forked from TrueCloudLab/frostfs-node
132 lines
2.2 KiB
Go
132 lines
2.2 KiB
Go
package workers
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/nspcc-dev/neofs-node/cmd/neofs-node/modules/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
|
|
}
|