Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 0 additions & 73 deletions chain.go

This file was deleted.

9 changes: 5 additions & 4 deletions cron.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type removal struct {
// be inspected while running.
type Cron struct {
entries entryHeap
chain Chain
overlap func(func(), *slog.Logger) func()
stop chan struct{}
add chan insertion
remove chan removal
Expand Down Expand Up @@ -90,7 +90,7 @@ type Entry struct {
func New(opts ...Option) *Cron {
c := &Cron{
entries: entryHeap{},
chain: NewChain(),
overlap: func(cmd func(), logger *slog.Logger) func() { return cmd },
add: make(chan insertion),
stop: make(chan struct{}),
snapshot: make(chan chan []Entry),
Expand Down Expand Up @@ -130,11 +130,12 @@ func (c *Cron) Schedule(schedule Schedule, cmd func()) (ID, error) {
return 0, fmt.Errorf("run out of available ids")
}

logger := c.logger.With("id", c.next)
entry := &Entry{
ID: c.next,
Schedule: schedule,
job: c.chain.Then(cmd),
logger: c.logger.With("id", c.next),
job: c.overlap(cmd, logger),
logger: logger,
}
c.next++
if !c.running {
Expand Down
44 changes: 36 additions & 8 deletions option.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package cron

import (
"log/slog"
"sync"
"time"
)

// Option represents a modification to the default behavior of a Cron.
Expand All @@ -22,14 +24,6 @@ func WithParser(p Parser) Option {
}
}

// WithChain specifies Job wrappers to apply to all jobs added to this cron.
// Refer to the Chain* functions in this package for provided wrappers.
func WithChain(wrappers ...JobWrapper) Option {
return func(c *Cron) {
c.chain = NewChain(wrappers...)
}
}

// WithLogger uses the provided logger.
func WithLogger(logger *slog.Logger) Option {
return func(c *Cron) {
Expand All @@ -54,3 +48,37 @@ func WithOnCycleCompleted(f func()) Option {
c.onCycleCompleted = append(c.onCycleCompleted, f)
}
}

func WithSkipIfRunning() Option {
return func(c *Cron) {
c.overlap = func(cmd func(), logger *slog.Logger) func() {
var ch = make(chan struct{}, 1)
ch <- struct{}{}
return func() {
select {
case v := <-ch:
defer func() { ch <- v }()
default:
logger.Info("job execution skipped", "event", "skip")
}
}
}
}
}

func WithQueueIfStillRunning() Option {
return func(c *Cron) {
c.overlap = func(cmd func(), logger *slog.Logger) func() {
var mu sync.Mutex
return func() {
start := time.Now()
mu.Lock()
defer mu.Unlock()
if dur := time.Since(start); dur > time.Minute {
logger.Info("job execution delayed", "event", "delay", "duration", dur)
}
cmd()
}
}
}
}
Loading