cron

package
v0.42.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 13, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package cron schedules recurring agent tasks. The loop sleeps until the next due job (no fixed tick) and wakes on job changes.

Delivery is at-most-once, deliberately. A job's message is a prompt, not a text: it can send mail, run a command, or spend money, so a run repeated because nobody could tell whether the first one finished is worse than a run missed. A tick is therefore marked before its turn starts, and a process killed mid-turn leaves it marked. The one place that degrades to at-least- once is a one-off whose deletion could not be written to disk: the store still holds it, and the next process runs it again.

jobs.json is shared by every factor process on the machine, so each read-modify-write cycle takes a lock file as well as this process's mutex. Without it two processes both write the whole store from what each read a moment earlier, and the loser's reminder is gone after its user was told it was scheduled.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Deliver

type Deliver func(channel, chatID, content string)

Deliver sends a job result to its channel/chat.

type Handler

type Handler func(ctx context.Context, job Job) (string, error)

Handler runs one due job and returns the text to deliver ("" = silent).

type Job

type Job struct {
	ID       string    `json:"id"`
	Schedule string    `json:"schedule,omitempty"` // cron expression; empty on a one-shot
	At       time.Time `json:"at,omitzero"`        // one-shot: the moment to run, then it is gone
	Message  string    `json:"message"`            // prompt run as an agent turn
	Channel  string    `json:"channel"`            // where to deliver the result
	ChatID   string    `json:"chat_id"`
	Enabled  bool      `json:"enabled"`
	LastRun  time.Time `json:"last_run,omitzero"`
}

A Job is either recurring or one-shot: Schedule holds a cron expression, or At holds the single moment to run at. One-shots exist because most of what a person asks for is one — "remind me at four" — and a cron expression cannot say it: the nearest thing, a date and month, comes round again every year.

func (Job) Once added in v0.35.0

func (j Job) Once() bool

Once reports whether this job runs one time and is then deleted.

type Service

type Service struct {
	// contains filtered or unexported fields
}

func NewService

func NewService(dir string, handler Handler, deliver Deliver) (*Service, error)

func (*Service) Add

func (s *Service) Add(schedule, message, channelName, chatID string) (Job, error)

Add validates and persists a new recurring job, waking the scheduler.

func (*Service) AddOnce added in v0.35.0

func (s *Service) AddOnce(at time.Time, message, channelName, chatID string) (Job, error)

AddOnce persists a job that runs at a single moment and is then deleted. A moment already gone by is refused rather than fired immediately: it is almost always a reminder worked out against the wrong day, and the caller can only notice that if somebody says so.

func (*Service) Idle added in v0.38.1

func (s *Service) Idle() bool

Idle reports that no job this scheduler dispatched is still running.

func (*Service) JobTimeout added in v0.41.1

func (s *Service) JobTimeout() time.Duration

JobTimeout is the deadline a scheduled turn runs under.

func (*Service) List

func (s *Service) List() []Job

List returns a snapshot of all jobs, including any another process has added since this one started.

func (*Service) Remove

func (s *Service) Remove(id string) error

Remove deletes a job.

func (*Service) Run

func (s *Service) Run(ctx context.Context)

Run is the scheduler loop; it blocks until ctx is done.

func (*Service) Scheduling added in v0.38.1

func (s *Service) Scheduling() bool

Scheduling reports whether due jobs will actually be run — by this process, or by one this service was told to look for. A `factor chat` that schedules a reminder into a store nobody is watching has promised something it cannot keep, and the only honest thing is to say so as it is written down.

func (*Service) SetEnabled

func (s *Service) SetEnabled(id string, enabled bool) error

SetEnabled toggles a job.

func (*Service) SetJobTimeout added in v0.41.1

func (s *Service) SetJobTimeout(d time.Duration)

SetJobTimeout bounds every scheduled turn this service dispatches.

func (*Service) SetSchedulerCheck added in v0.38.1

func (s *Service) SetSchedulerCheck(fn func() bool)

SetSchedulerCheck teaches this service how to see a scheduler in another process — the gateway, from a terminal that only writes to the store.

func (*Service) Wait added in v0.38.1

func (s *Service) Wait(timeout time.Duration)

Wait blocks until the jobs already dispatched have finished, or timeout passes. The gateway calls it on the way down: a scheduled turn is a real turn, and a process that exits through the middle of one leaves nothing where an answer was owed — the more so for a one-off, which is no longer in the store to be run again.

type Tool

type Tool struct{ Service *Service }

Tool lets the agent manage its own schedule. The channel/chat a job is created from becomes its delivery target.

func (*Tool) Description

func (t *Tool) Description() string

func (*Tool) Execute

func (t *Tool) Execute(ctx context.Context, args map[string]any) *tools.Result

func (*Tool) Name

func (t *Tool) Name() string

func (*Tool) Parameters

func (t *Tool) Parameters() map[string]any

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL