Files
base/tools/cron/job.go
zeekay 1c40839ccb refactor(cron): route every scheduled-job path through tools/tasks
tools/cron is now a thin alias over tools/tasks. The legacy ticker +
crontab-matching implementation is deleted; the public surface (New,
Add/MustAdd, Remove, RemoveAll, Jobs, HasJob, Total, Start, Stop,
SetInterval, SetTimezone, HasStarted) is preserved so no callsite
changes. app.Cron() and app.Tasks() share a single *tasks.Client, giving
one obvious way to schedule work.

- tools/tasks/client.go gains the primitives the cron shim needs
  (Remove, RemoveAll, HasJob, Total, Schedules, Run, PauseAll, ResumeAll,
  ActiveTickerCount) plus a richer internal scheduleEntry so remote vs
  local ticking are distinguishable.
- cron.Cron.Stop() now pauses local tickers while preserving the
  registry, matching the legacy semantics expected by ResetBootstrapState
  and the admin API.
- core/base.go builds app.cron via cron.NewFromTasks(app.tasks) so both
  accessors feed the same state.
- apis/cron.go keeps the /crons list + run-now behaviour; lookup now
  uses HasJob() for an O(1) precheck.

Tests rewritten around the shim (TestCronDelegatesToTasks,
TestCronAppFacadeLocal, TestCronAppFacadeRemoteFallback,
TestCronNewFromTasksShared). Legacy 1-minute-tick assertions
(TestCronStartStop) are SKIPped with a pointer to their replacement;
crontab parser tests (tools/cron/schedule_test.go) still pass — the
parser stays as a validation primitive for settings_model.go.

docs/cron-to-tasks.md covers the migration path for services.
2026-04-22 15:14:45 -07:00

40 lines
996 B
Go

package cron
import (
"encoding/json"
"github.com/hanzoai/base/tools/tasks"
)
// Job is a read-only view of a registered schedule, returned by Cron.Jobs().
type Job struct {
id string
expression string
client *tasks.Client
}
// Id returns the job id.
func (j *Job) Id() string { return j.id }
// Expression returns the cron expression or duration string the job was
// registered with.
func (j *Job) Expression() string { return j.expression }
// Run invokes the job's registered callback immediately, outside the normal
// schedule. No-op if the callback runs server-side (durable tasks) and is
// therefore not available in-process.
func (j *Job) Run() {
if j.client == nil {
return
}
j.client.Run(j.id)
}
// MarshalJSON implements json.Marshaler for the admin list endpoint.
func (j Job) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
Id string `json:"id"`
Expression string `json:"expression"`
}{Id: j.id, Expression: j.expression})
}