Documentation
¶
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrNilConfig indicates nil was given as config. ErrNilConfig = errors.New("ztime/zcron: nil config") // ErrNilJob indicates nil job function was given. ErrNilJob = errors.New("ztime/zcron: nil job function") )
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
// Crontab is the cron expression.
// See [Parse] for the syntax.
Crontab string
// MaxConcurrency is the maximum concurrency
// of the currently running JobFunc.
// Values should be 1, 2, ...
// 1 means exactly 1 job at a time.
// If less than 1, 1 is used.
MaxConcurrency int
// MaxRetry is the maximum number to retry
// when the JobFunc returned non-nil error.
// Values should be 0, 1, 2, ...
// 0 means no retry. If less than 0, 0 is used.
MaxRetry int
// JobFunc is the job to run.
JobFunc func(context.Context) error
// WithContext provides a context which passed to the [Job.Run].
// This is called once for a run and not called for retry.
// [context.Background] is used when WithContext is nil.
WithContext func() context.Context
// EventHook is the function that hooks [Event]s.
// The [Event] is notified through the first argument.
// Additional information such as error is passed by a
// depending on the event type.
// - For OnJobFailed: error is given by a[0].
// - For OnJobPanicked: recovered value given by a[0].
EventHook func(e Event, a ...any)
}
Config is the configuration for the Cron.
type Cron ¶
type Cron struct {
// contains filtered or unexported fields
}
Cron schedules and runs jobs based on Crontab.
Example ¶
package main
import (
"context"
"fmt"
"time"
"github.com/aileron-projects/go/ztime/zcron"
)
func main() {
now := time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)
count := 0
stop := make(chan struct{})
job, _ := zcron.NewCron(&zcron.Config{
Crontab: "* * * * * *",
JobFunc: func(ctx context.Context) error {
if count++; count > 3 {
stop <- struct{}{}
return nil
}
now = now.Add(time.Second)
fmt.Println(now.Format(time.DateTime), "Hello Go!")
return nil
},
})
job.WithTimeFunc(func() time.Time { return now })
go job.Start()
<-stop
}
Output: 2000-01-01 00:00:01 Hello Go! 2000-01-01 00:00:02 Hello Go! 2000-01-01 00:00:03 Hello Go!
func (*Cron) Start ¶
func (c *Cron) Start()
Start starts the cron. The cron scheduling can only run 1 process at a time. Calling Start multiple times does not run the multiple crons. If the next scheduling is after 10 minutes or more, the internal timer calibrates the time after 95% of the times. For examples, now a job is scheduled after 10 minutes, the con calibrates timer to fire the job after 9min30sec. It blocks the process. Run in a new goroutine if blocking is not necessary like below.
cron, _ := zcron.NewCron(.....) go cron.Start()
func (*Cron) Stop ¶
func (c *Cron) Stop()
Stop stops new scheduling of jobs. Stopping cron does not stop the already running jobs.
func (*Cron) WithTimeAfterFunc ¶
WithTimeAfterFunc replaces internal wait functions.
func (*Cron) WithTimeFunc ¶
WithTimeFunc replaces internal clock.
type Crontab ¶
type Crontab struct {
// contains filtered or unexported fields
}
Crontab is a cron scheduler.
Example ¶
package main
import (
"fmt"
"time"
"github.com/aileron-projects/go/ztime/zcron"
)
func main() {
ct, err := zcron.Parse("59 59 23 31 * *") // Schedule at 31st at 23:59:59
if err != nil {
panic(err)
}
// Replace internal clock for testing.
now := time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)
ct.WithTimeFunc(func() time.Time { return now })
for range 10 {
fmt.Println(now.Format(time.DateTime), "|", ct.Next().Format(time.DateTime))
now = now.Add(15 * 24 * time.Hour) // Forward 15 days.
}
}
Output: 2000-01-01 00:00:00 | 2000-01-31 23:59:59 2000-01-16 00:00:00 | 2000-01-31 23:59:59 2000-01-31 00:00:00 | 2000-01-31 23:59:59 2000-02-15 00:00:00 | 2000-03-31 23:59:59 2000-03-01 00:00:00 | 2000-03-31 23:59:59 2000-03-16 00:00:00 | 2000-03-31 23:59:59 2000-03-31 00:00:00 | 2000-03-31 23:59:59 2000-04-15 00:00:00 | 2000-05-31 23:59:59 2000-04-30 00:00:00 | 2000-05-31 23:59:59 2000-05-15 00:00:00 | 2000-05-31 23:59:59
Example (EverySeconds) ¶
package main
import (
"fmt"
"time"
"github.com/aileron-projects/go/ztime/zcron"
)
func main() {
ct, err := zcron.Parse("* * * * * *") // Every seconds.
if err != nil {
panic(err)
}
// Replace internal clock for testing.
now := time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)
ct.WithTimeFunc(func() time.Time { return now })
for range 6 {
fmt.Println(now.Format(time.DateTime), "|", ct.Next().Format(time.DateTime))
now = now.Add(500 * time.Millisecond) // Forward 500ms.
}
}
Output: 2000-01-01 00:00:00 | 2000-01-01 00:00:01 2000-01-01 00:00:00 | 2000-01-01 00:00:01 2000-01-01 00:00:01 | 2000-01-01 00:00:02 2000-01-01 00:00:01 | 2000-01-01 00:00:02 2000-01-01 00:00:02 | 2000-01-01 00:00:03 2000-01-01 00:00:02 | 2000-01-01 00:00:03
func Parse ¶
Parse parses the given cron expression and returns Crontab. The syntax follows
TZ=UTC * * * * * * | | | | | | | | | | | | | |- Day of week | | | | | |--- Month | | | | |----- Day of month | | | |------- Hour | | |--------- Minute | |----------- Second (Optional) |------------------ Timezone (Optional) Field name | Mandatory | Values | Special characters ---------- | ---------- | -------------- | ------------------- Timezone | No | Timezone name | Second | No | 0-59 | * / , - Minute | Yes | 0-59 | * / , - Hours | Yes | 0-23 | * / , - Day of month | Yes | 1-31 | * / , - Month | Yes | 1-12 or JAN-DEC | * / , - Day of week | Yes | 0-6 or SUN-SAT | * / , -
Note that the "Day of month" and the "Day of week" are evaluated with AND condition.
Following aliases are defined for convenience.
Alias name | Alias value | Usage example | ---------- | ----------- | -------------------- | CRON_TZ | TZ | CRON_TZ=UTC 0 0 * * * | @monthly | 0 0 1 * * | TZ=UTC @monthly | @weekly | 0 0 * * 0 | TZ=UTC @weekly | @daily | 0 0 * * * | TZ=UTC @daily | @hourly | 0 * * * * | TZ=UTC @hourly | @sunday | 0 0 * * 0 | TZ=UTC @sunday | @monday | 0 0 * * 1 | TZ=UTC @monday | @tuesday | 0 0 * * 2 | TZ=UTC @tuesday | @wednesday | 0 0 * * 3 | TZ=UTC @wednesday | @thursday | 0 0 * * 4 | TZ=UTC @thursday | @friday | 0 0 * * 5 | TZ=UTC @friday | @saturday | 0 0 * * 6 | TZ=UTC @saturday |
In addition, "@every <Duration>" expression can be used. Format of the duration must follow the time.ParseDuration.
Example of "@every" expression.
Duration | Resolved Cron | Notes | --------- | -------------------- | --------------------- | -1s | ERROR | Duration must be >0s | 0s | ERROR | Duration must be >0s | 1s | */1 * * * * * | | 1m | 0 */1 * * * * | | 1h | 0 0 */1 * * * | | 61s | */1 */1 * * * | | 15m30s | */30 */15 * * * * | | 65m30s | */30 */5 */1 * * * | | 1h30m | 0 */30 */1 * * * | | 23h59m59s | */59 */59 */23 * * * | | 24h | ERROR | Duration must be <24h |
See the references.
func (*Crontab) Next ¶
Next returns the next cron scheduled time. It internally calls Crontab.NextAfter with the current time returned from the internal clock. Use Crontab.WithTimeFunc when replacing the internal clock.
func (*Crontab) NextAfter ¶
NexAfter returns the next cron scheduled time after t. Timezone of the returned time is the same as given t.
func (*Crontab) Now ¶
Now returns the current time returned from the internal clock. Use Crontab.WithTimeFunc to replace the internal clock.
func (*Crontab) WithTimeFunc ¶
type Event ¶
type Event int
Event is the event definition on cron. Following types of events are defined.
const ( Undefined Event = iota OnJobRun // OnJobRun triggered when job is scheduled and run. OnJobAccepted // OnJobAccepted triggered when job is accepted. OnJobDeclined // OnJobAccepted triggered when job is declined (Max concurrency reached). OnJobStarted // OnJobStarted triggered just before [Config.JobFunc] is called. OnJobExited // OnJobExited triggered just after [Config.JobFunc] is returned. OnJobFailed // OnJobFailed triggered when [Config.JobFunc] returned an error. This trigger is before [OnJobExited]. OnJobPanicked // OnJobPanicked triggered when [Config.JobFunc] panicked. This trigger is before [OnJobExited]. )
type ParseError ¶
ParseError reports cron parse error.
func (*ParseError) Error ¶
func (e *ParseError) Error() string
func (*ParseError) Is ¶
func (e *ParseError) Is(target error) bool
func (*ParseError) Unwrap ¶
func (e *ParseError) Unwrap() error