0
Fork 0
mirror of https://github.com/project-zot/zot.git synced 2025-01-06 22:40:28 -05:00
zot/pkg/extensions/search/cve/update.go
peusebiu 6f00e843a0
fix(sync): sync generator now backs off on errors (#2272)
handle unsupported features like oci artifacts.

closes: #2238

Signed-off-by: Petu Eusebiu <peusebiu@cisco.com>
2024-03-04 09:44:11 -08:00

135 lines
2.5 KiB
Go

package cveinfo
import (
"context"
"fmt"
"sync"
"time"
"zotregistry.dev/zot/pkg/log"
"zotregistry.dev/zot/pkg/scheduler"
)
type state int
const (
pending state = iota
running
done
)
func NewDBUpdateTaskGenerator(
interval time.Duration,
scanner Scanner,
log log.Logger,
) scheduler.TaskGenerator {
generator := &DBUpdateTaskGenerator{
interval,
scanner,
log,
pending,
0,
time.Now(),
&sync.Mutex{},
}
return generator
}
type DBUpdateTaskGenerator struct {
interval time.Duration
scanner Scanner
log log.Logger
status state
waitTime time.Duration
lastTaskTime time.Time
lock *sync.Mutex
}
func (gen *DBUpdateTaskGenerator) Name() string {
return "CVEDBUpdateGenerator"
}
func (gen *DBUpdateTaskGenerator) Next() (scheduler.Task, error) {
var newTask scheduler.Task
gen.lock.Lock()
if gen.status == pending && time.Since(gen.lastTaskTime) >= gen.waitTime {
newTask = newDBUpdadeTask(gen.interval, gen.scanner, gen, gen.log)
gen.status = running
}
gen.lock.Unlock()
return newTask, nil
}
func (gen *DBUpdateTaskGenerator) IsDone() bool {
gen.lock.Lock()
status := gen.status
gen.lock.Unlock()
return status == done
}
func (gen *DBUpdateTaskGenerator) IsReady() bool {
return true
}
func (gen *DBUpdateTaskGenerator) Reset() {
gen.lock.Lock()
gen.status = pending
gen.waitTime = 0
gen.lock.Unlock()
}
type dbUpdateTask struct {
interval time.Duration
scanner Scanner
generator *DBUpdateTaskGenerator
log log.Logger
}
func newDBUpdadeTask(interval time.Duration, scanner Scanner,
generator *DBUpdateTaskGenerator, log log.Logger,
) *dbUpdateTask {
return &dbUpdateTask{interval, scanner, generator, log}
}
func (dbt *dbUpdateTask) DoWork(ctx context.Context) error {
dbt.log.Info().Msg("updating cve-db")
err := dbt.scanner.UpdateDB(ctx)
if err != nil {
dbt.generator.lock.Lock()
dbt.generator.status = pending
if dbt.generator.waitTime == 0 {
dbt.generator.waitTime = time.Second
}
dbt.generator.waitTime *= 2
dbt.generator.lastTaskTime = time.Now()
dbt.generator.lock.Unlock()
return err
}
dbt.generator.lock.Lock()
dbt.generator.lastTaskTime = time.Now()
dbt.generator.status = done
dbt.generator.lock.Unlock()
dbt.log.Info().Interface("interval", dbt.interval).Msg("cve-db update completed, next update scheduled after interval")
return nil
}
func (dbt *dbUpdateTask) String() string {
return fmt.Sprintf("{Name: %s}", dbt.Name())
}
func (dbt *dbUpdateTask) Name() string {
return "DBUpdateTask"
}