Help us shape the future of Go! Take the 2026 Go Developer Survey

schedule

package
v0.24.0 Latest Latest
Warning

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

Go to latest
Published: Oct 17, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package schedule runs recurring tasks: functions, app commands and queue jobs, on cron expressions or helpers such as DailyAt.

s.Command("reports:send").DailyAt("08:00").WithoutOverlapping()
s.Job(jobs.PruneSessions{}).Hourly()
s.Func("ping", func(ctx context.Context) error { ... }).EveryFiveMinutes()

Run it in process with Work (vukem schedule:work) or from one cron entry calling RunDue every minute (vukem schedule:run). Schedule holds the Task list, Cron parses five-field expressions, and WithoutOverlapping takes a lock in the Options.Locks cache.

See https://github.com/AlexGalhardo/vukem/blob/main/docs/subsystems.md#scheduler.

Example
package main

import (
	"context"
	"fmt"
	"time"

	"github.com/AlexGalhardo/vukem/schedule"
)

func main() {
	s := schedule.New(schedule.Options{})
	s.Func("ping", func(context.Context) error { return nil }).EveryFiveMinutes()
	s.Command("reports:send").DailyAt("08:00").WithoutOverlapping()

	for _, t := range s.Tasks() {
		fmt.Println(t.Name(), t.Expression())
	}

	now := time.Date(2026, 1, 5, 8, 0, 0, 0, time.UTC)
	for _, t := range s.Due(now) {
		fmt.Println("due at 08:00:", t.Name())
	}
}
Output:
ping */5 * * * *
reports:send 0 8 * * *
due at 08:00: ping
due at 08:00: reports:send

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrCron = errors.New("schedule: invalid cron expression")

ErrCron reports an invalid expression.

Functions

This section is empty.

Types

type Cron

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

Cron is a parsed five-field cron expression (minute hour day-of-month month day-of-week) with the usual syntax: "*", "5", "1-5", "*/15", "10-50/10", lists ("1,15"), month and weekday names ("JAN", "MON"), and the macros @yearly, @monthly, @weekly, @daily, @hourly. As in Vixie cron, when both day fields are restricted a day matches either.

func MustParseCron

func MustParseCron(expr string) Cron

MustParseCron is ParseCron that panics (for literals).

func ParseCron

func ParseCron(expr string) (Cron, error)

ParseCron parses expr.

Example
package main

import (
	"fmt"
	"time"

	"github.com/AlexGalhardo/vukem/schedule"
)

func main() {
	c, err := schedule.ParseCron("30 9 * * 1-5")
	if err != nil {
		fmt.Println(err)
		return
	}

	from := time.Date(2026, 1, 3, 12, 0, 0, 0, time.UTC) // a Saturday
	fmt.Println(c.Next(from).Format(time.RFC1123))
}
Output:
Mon, 05 Jan 2026 09:30:00 UTC

func (Cron) Matches

func (c Cron) Matches(t time.Time) bool

Matches reports whether t (to the minute, in t's location) is a run time.

func (Cron) Next

func (c Cron) Next(t time.Time) time.Time

Next returns the first run time strictly after t (in t's location), or the zero time if there is none within five years.

func (Cron) String

func (c Cron) String() string

String returns the expression as given.

type Options

type Options struct {
	// Location is the default time zone of expressions (default UTC).
	Location *time.Location
	// Log receives task outcomes (default slog.Default()).
	Log *slog.Logger
	// Locks backs WithoutOverlapping (default an in-memory store, which
	// only protects one process; use the database or Redis cache store
	// when several servers run the schedule).
	Locks *cache.Cache
	// Commands runs app commands for Command tasks.
	Commands func(ctx context.Context, name string, args []string) error
	// Queue dispatches Job tasks.
	Queue func() (*queue.Queue, error)
	// StopTimeout is how long Work waits for running tasks once its
	// context is cancelled before cancelling theirs (default 30s). Tasks
	// must honor ctx; one that ignores it still holds Work.
	StopTimeout time.Duration
}

Options configure a Schedule.

type Schedule

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

Schedule holds the tasks.

func New

func New(o Options) *Schedule

New returns an empty schedule.

func (*Schedule) Command

func (s *Schedule) Command(name string, args ...string) *Task

Command schedules an app command with args.

func (*Schedule) Due

func (s *Schedule) Due(now time.Time) []*Task

Due returns the tasks due at now (to the minute).

func (*Schedule) Func

func (s *Schedule) Func(name string, fn func(ctx context.Context) error) *Task

Func schedules fn under name.

func (*Schedule) Job

func (s *Schedule) Job(j queue.Job, opts ...queue.Option) *Task

Job schedules dispatching j onto the queue.

func (*Schedule) Next

func (s *Schedule) Next(t *Task, now time.Time) time.Time

Next returns when t runs next after now.

func (*Schedule) RunDue

func (s *Schedule) RunDue(ctx context.Context, now time.Time) error

RunDue runs the tasks due at now concurrently and waits for them. Task errors are logged and joined into the result.

func (*Schedule) Tasks

func (s *Schedule) Tasks() []*Task

Tasks returns the tasks in registration order.

func (*Schedule) Work

func (s *Schedule) Work(ctx context.Context, now func() time.Time) error

Work runs due tasks at the start of every minute until ctx is cancelled, then waits for running tasks up to Options.StopTimeout and cancels their context. now is the clock (time.Now if nil).

type Task

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

Task is a scheduled unit of work; configure it with the chained methods.

func (*Task) Cron

func (t *Task) Cron(expr string) *Task

Cron sets a cron expression; it panics on a bad expression, so mistakes surface at boot.

func (*Task) Daily

func (t *Task) Daily() *Task

Daily runs the task at midnight.

func (*Task) DailyAt

func (t *Task) DailyAt(hhmm string) *Task

DailyAt runs the task every day at "HH:MM".

func (*Task) Every

func (t *Task) Every(d time.Duration) *Task

Every runs the task every d, aligned to the clock (d must be a whole number of minutes dividing an hour or a day, e.g. 5m, 15m, 2h).

func (*Task) EveryFiveMinutes

func (t *Task) EveryFiveMinutes() *Task

EveryFiveMinutes runs the task every five minutes.

func (*Task) EveryMinute

func (t *Task) EveryMinute() *Task

EveryMinute runs the task every minute.

func (*Task) Expression

func (t *Task) Expression() string

Expression returns the cron expression.

func (*Task) Hourly

func (t *Task) Hourly() *Task

Hourly runs the task at the start of every hour.

func (*Task) HourlyAt

func (t *Task) HourlyAt(minute int) *Task

HourlyAt runs the task every hour at minute.

func (*Task) In

func (t *Task) In(loc *time.Location) *Task

In sets the time zone of the task's expression.

func (*Task) MonthlyOn

func (t *Task) MonthlyOn(day int, hhmm string) *Task

MonthlyOn runs the task on day of the month at "HH:MM".

func (*Task) Name

func (t *Task) Name() string

Name returns the task's label.

func (*Task) Weekdays

func (t *Task) Weekdays() *Task

Weekdays restricts the task to Monday-Friday (keeps its time).

func (*Task) WeeklyOn

func (t *Task) WeeklyOn(weekday time.Weekday, hhmm string) *Task

WeeklyOn runs the task on weekday (0 = Sunday) at "HH:MM".

func (*Task) WithoutOverlapping

func (t *Task) WithoutOverlapping(ttl ...time.Duration) *Task

WithoutOverlapping skips a run while the previous one still holds the lock (released when it ends, or after ttl; default 24h).

Jump to

Keyboard shortcuts

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