diff --git a/.golangci.yml b/.golangci.yml index a995456..33eab8e 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -286,7 +286,7 @@ linters: # Checks the number of lines in a function. # If lower than 0, disable the check. # Default: 60 - lines: 100 + lines: 250 # Checks the number of statements in a function. # If lower than 0, disable the check. # Default: 40 diff --git a/cmd/cachewd/main.go b/cmd/cachewd/main.go index b41814c..2363a36 100644 --- a/cmd/cachewd/main.go +++ b/cmd/cachewd/main.go @@ -70,11 +70,9 @@ func main() { return tokenManagerProvider() }) - scheduler, err := jobscheduler.New(ctx, globalConfig.SchedulerConfig) - kctx.FatalIfErrorf(err, "failed to create scheduler") - defer scheduler.Close() + schedulerProvider := jobscheduler.NewProvider(ctx, globalConfig.SchedulerConfig) - cr, sr := newRegistries(scheduler, managerProvider, tokenManagerProvider) + cr, sr := newRegistries(schedulerProvider, managerProvider, tokenManagerProvider) // Commands switch { //nolint:gocritic @@ -105,7 +103,7 @@ func main() { kctx.FatalIfErrorf(err) } -func newRegistries(scheduler jobscheduler.Scheduler, cloneManagerProvider gitclone.ManagerProvider, tokenManagerProvider githubapp.TokenManagerProvider) (*cache.Registry, *strategy.Registry) { +func newRegistries(scheduler jobscheduler.Provider, cloneManagerProvider gitclone.ManagerProvider, tokenManagerProvider githubapp.TokenManagerProvider) (*cache.Registry, *strategy.Registry) { cr := cache.NewRegistry() cache.RegisterMemory(cr) cache.RegisterDisk(cr) diff --git a/internal/jobscheduler/jobs.go b/internal/jobscheduler/jobs.go index 46e10fc..f6f383f 100644 --- a/internal/jobscheduler/jobs.go +++ b/internal/jobscheduler/jobs.go @@ -80,6 +80,15 @@ type RootScheduler struct { var _ Scheduler = &RootScheduler{} +type Provider func() (*RootScheduler, error) + +// NewProvider returns a scheduler singleton provider function. +func NewProvider(ctx context.Context, config Config) Provider { + return sync.OnceValues(func() (*RootScheduler, error) { + return New(ctx, config) + }) +} + // New creates a new JobScheduler. func New(ctx context.Context, config Config) (*RootScheduler, error) { if config.Concurrency == 0 { diff --git a/internal/strategy/git/git.go b/internal/strategy/git/git.go index a53d977..9852980 100644 --- a/internal/strategy/git/git.go +++ b/internal/strategy/git/git.go @@ -27,7 +27,7 @@ import ( "github.com/block/cachew/internal/strategy" ) -func Register(r *strategy.Registry, scheduler jobscheduler.Scheduler, cloneManagerProvider gitclone.ManagerProvider, tokenManagerProvider githubapp.TokenManagerProvider) { +func Register(r *strategy.Registry, scheduler jobscheduler.Provider, cloneManagerProvider gitclone.ManagerProvider, tokenManagerProvider githubapp.TokenManagerProvider) { strategy.Register(r, "git", "Caches Git repositories, including tarball snapshots.", func(ctx context.Context, config Config, cache cache.Cache, mux strategy.Mux) (*Strategy, error) { return New(ctx, config, scheduler, cache, mux, cloneManagerProvider, tokenManagerProvider) }) @@ -54,7 +54,7 @@ type Strategy struct { func New( ctx context.Context, config Config, - scheduler jobscheduler.Scheduler, + schedulerProvider jobscheduler.Provider, cache cache.Cache, mux strategy.Mux, cloneManagerProvider gitclone.ManagerProvider, @@ -94,6 +94,11 @@ func New( } } + scheduler, err := schedulerProvider() + if err != nil { + return nil, errors.Wrap(err, "failed to create scheduler") + } + s := &Strategy{ config: config, cache: cache, diff --git a/internal/strategy/git/git_test.go b/internal/strategy/git/git_test.go index fb64fa7..aa8e1ba 100644 --- a/internal/strategy/git/git_test.go +++ b/internal/strategy/git/git_test.go @@ -34,12 +34,9 @@ func (m *testMux) HandleFunc(pattern string, handler func(http.ResponseWriter, * m.handlers[pattern] = http.HandlerFunc(handler) } -func newTestScheduler(ctx context.Context, t *testing.T) jobscheduler.Scheduler { +func newTestScheduler(ctx context.Context, t *testing.T) jobscheduler.Provider { t.Helper() - s, err := jobscheduler.New(ctx, jobscheduler.Config{}) - assert.NoError(t, err) - t.Cleanup(func() { s.Close() }) - return s + return jobscheduler.NewProvider(ctx, jobscheduler.Config{}) } func TestNew(t *testing.T) {