Initial commit: IT Nexus Web-App

This commit is contained in:
2026-06-01 20:49:07 +02:00
commit 8023765e6c
387 changed files with 106900 additions and 0 deletions

View File

@@ -0,0 +1,63 @@
package scheduler
import (
"context"
"log/slog"
"time"
"github.com/cereda-systems/nexus-scanner/internal/module"
)
// Scheduler runs registered modules at their configured intervals.
type Scheduler struct {
registry *module.Registry
}
// New returns a new Scheduler backed by the given registry.
func New(registry *module.Registry) *Scheduler {
return &Scheduler{registry: registry}
}
// Run starts all modules in background goroutines and blocks until ctx is cancelled.
func (s *Scheduler) Run(ctx context.Context) {
for _, m := range s.registry.All() {
go s.runModule(ctx, m)
}
<-ctx.Done()
}
func (s *Scheduler) runModule(ctx context.Context, m module.Module) {
log := slog.With("module", m.Name())
// Run immediately on startup.
s.execute(ctx, m, log)
// If interval is zero, run once and stop.
if m.Interval() == 0 {
return
}
ticker := time.NewTicker(m.Interval())
defer ticker.Stop()
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
s.execute(ctx, m, log)
}
}
}
func (s *Scheduler) execute(ctx context.Context, m module.Module, log *slog.Logger) {
log.Info("run started")
start := time.Now()
if err := m.Run(ctx); err != nil {
log.Error("run failed", "err", err, "elapsed", time.Since(start).Round(time.Millisecond))
return
}
log.Info("run completed", "elapsed", time.Since(start).Round(time.Millisecond))
}