feat(11-02): run plugin schedules as River periodic jobs through bonfire.Call
- pact.HasSchedule with ScheduledCommand and Daily/DailyAt/Every cadences (no River import) - bonfire.Call, Catalog and ErrUnknownCommand for in-process command runs - conga Daily/Every wall-clock schedules in app.timezone, periodic jobs on every worker, scheduled queue (MaxAttempts 1, unique by args within the cadence period) - scheduled worker runs only entries matching the compiled table; unregistered commands are skipped with a Warn log - generated app main publishes bonfire.NewCatalog(commands); hello main regenerated
This commit is contained in:
@@ -55,6 +55,11 @@ func (w *Worker) Queues() []string {
|
||||
// from database.dsn, so jobs committed by any process are picked up without
|
||||
// waiting for the poll interval. The worker keeps running after ctx is
|
||||
// cancelled; stop it with Worker.Stop.
|
||||
//
|
||||
// Every worker also carries the River periodic jobs of plugins'
|
||||
// pact.HasSchedule entries (only the elected leader enqueues them) and runs
|
||||
// the built-in scheduled command job on QueueScheduled when that queue is
|
||||
// selected. An invalid schedule entry or app.timezone fails the start.
|
||||
func StartWorker(ctx context.Context, app *backpack.App, plugins []party.Plugin, o WorkerOptions) (*Worker, error) {
|
||||
m, err := From(app)
|
||||
if err != nil {
|
||||
@@ -77,13 +82,23 @@ func StartWorker(ctx context.Context, app *backpack.App, plugins []party.Plugin,
|
||||
}
|
||||
s := settingsFromApp(app)
|
||||
log := loggerFromApp(app)
|
||||
periodic, table, err := periodicJobs(app, plugins)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
if m.worker != nil {
|
||||
return nil, fmt.Errorf("conga: a worker is already running")
|
||||
}
|
||||
if err := m.registerLocked(m.scheduledJobLocked()); err != nil {
|
||||
return nil, fmt.Errorf("conga: register scheduled command job: %w", err)
|
||||
}
|
||||
known := knownQueues(s, m.jobs)
|
||||
if _, configured := s.queues[QueueScheduled]; !configured {
|
||||
known[QueueScheduled] = scheduledMaxWorkers
|
||||
}
|
||||
queues, err := selectQueues(known, o.Queues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -103,6 +118,9 @@ func StartWorker(ctx context.Context, app *backpack.App, plugins []party.Plugin,
|
||||
}
|
||||
cfg := baseConfig(s, log)
|
||||
cfg.Workers = workers
|
||||
// Every worker carries the periodic jobs whatever its queue filter:
|
||||
// only the elected leader enqueues them.
|
||||
cfg.PeriodicJobs = periodic
|
||||
cfg.Queues = map[string]river.QueueConfig{}
|
||||
for name, n := range queues {
|
||||
cfg.Queues[name] = river.QueueConfig{MaxWorkers: n}
|
||||
@@ -135,6 +153,7 @@ func StartWorker(ctx context.Context, app *backpack.App, plugins []party.Plugin,
|
||||
return nil, fmt.Errorf("conga: start worker: %w", err)
|
||||
}
|
||||
m.worker = client
|
||||
m.schedule = table
|
||||
return &Worker{m: m, client: client, listener: listener, queues: sortedQueueNames(queues)}, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user