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:
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"io/fs"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"git.golem15.com/golem15/summercms/modules/bonfire"
|
||||
"github.com/go-gormigrate/gormigrate/v2"
|
||||
@@ -98,6 +99,77 @@ type HasJobs interface {
|
||||
Jobs() []Job
|
||||
}
|
||||
|
||||
type cadenceKind uint8
|
||||
|
||||
const (
|
||||
cadenceNone cadenceKind = iota
|
||||
cadenceDaily
|
||||
cadenceEvery
|
||||
)
|
||||
|
||||
// Cadence is how often a scheduled command runs. Build one with Daily,
|
||||
// DailyAt or Every; the zero value is no cadence and is rejected by the
|
||||
// scheduler.
|
||||
type Cadence struct {
|
||||
kind cadenceKind
|
||||
hour int
|
||||
minute int
|
||||
every time.Duration
|
||||
}
|
||||
|
||||
// Daily runs once a day at 00:00 in the app timezone (Laravel ->daily()).
|
||||
func Daily() Cadence { return DailyAt(0, 0) }
|
||||
|
||||
// DailyAt runs once a day at hour:minute in the app timezone.
|
||||
func DailyAt(hour, minute int) Cadence {
|
||||
return Cadence{kind: cadenceDaily, hour: hour, minute: minute}
|
||||
}
|
||||
|
||||
// Every runs at every multiple of d since local midnight in the app
|
||||
// timezone. The scheduler requires d to be at least one second and to divide
|
||||
// 24h evenly.
|
||||
func Every(d time.Duration) Cadence {
|
||||
return Cadence{kind: cadenceEvery, every: d}
|
||||
}
|
||||
|
||||
// IsZero reports whether c is the zero Cadence.
|
||||
func (c Cadence) IsZero() bool { return c.kind == cadenceNone }
|
||||
|
||||
// Interval is the period of c: 24h for a daily cadence, d for Every(d) and
|
||||
// zero for the zero Cadence.
|
||||
func (c Cadence) Interval() time.Duration {
|
||||
switch c.kind {
|
||||
case cadenceDaily:
|
||||
return 24 * time.Hour
|
||||
case cadenceEvery:
|
||||
return c.every
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// At returns the wall-clock time of a daily cadence; ok is false for Every
|
||||
// and for the zero Cadence.
|
||||
func (c Cadence) At() (hour, minute int, ok bool) {
|
||||
if c.kind != cadenceDaily {
|
||||
return 0, 0, false
|
||||
}
|
||||
return c.hour, c.minute, true
|
||||
}
|
||||
|
||||
// ScheduledCommand is one recurring run of a registered console command.
|
||||
// Command is the command name (namespace:verb) and Args its arguments.
|
||||
type ScheduledCommand struct {
|
||||
Command string
|
||||
Args []string
|
||||
Cadence Cadence
|
||||
}
|
||||
|
||||
// HasSchedule is implemented by plugins that run console commands on a
|
||||
// schedule. Only these compiled entries are ever executed by the scheduler.
|
||||
type HasSchedule interface {
|
||||
Schedule() []ScheduledCommand
|
||||
}
|
||||
|
||||
// AdminController is the compile-time admin controller contract. Phase 9
|
||||
// grows the schema pipeline; ID, model name and YAML config directory are
|
||||
// enough for generated stubs to compile.
|
||||
@@ -369,10 +441,10 @@ type OptionalMessage interface {
|
||||
// packages exist:
|
||||
//
|
||||
// HasListeners
|
||||
// HasSchedule
|
||||
//
|
||||
// The kernel type-asserts HasConfig (party, before Register), HasCommands
|
||||
// (generated app main, after Boot), HasMigrations (lagoon migrate), and
|
||||
// (generated app main, after Boot), HasMigrations (lagoon migrate),
|
||||
// HasJobs and HasSchedule (conga workers), and
|
||||
// HasMiddleware/HasMiddlewareFactories/HasHouseMiddleware/HasRoutes
|
||||
// (surf assemble). surf.BucketProvider is type-asserted in Assemble/
|
||||
// BuildRouter (not a pact interface: pact cannot import surf without a cycle).
|
||||
|
||||
Reference in New Issue
Block a user