Skip to content

Commit 55e65f9

Browse files
committed
Add basic cron concept for periodic commands
1 parent 0a47b26 commit 55e65f9

1 file changed

Lines changed: 69 additions & 0 deletions

File tree

backend/cron/cron.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package cron
2+
3+
import (
4+
"context"
5+
"log/slog"
6+
"sync"
7+
"time"
8+
9+
"github.com/theandrew168/bloggulus/backend/command"
10+
)
11+
12+
type Cron struct {
13+
cmd *command.Command
14+
}
15+
16+
type Job struct {
17+
Interval time.Duration
18+
RunNow bool
19+
Run func(cmd *command.Command) error
20+
}
21+
22+
func NewCron(cmd *command.Command) *Cron {
23+
c := Cron{
24+
cmd: cmd,
25+
}
26+
return &c
27+
}
28+
func (c *Cron) Run(ctx context.Context, jobs []Job) error {
29+
var wg sync.WaitGroup
30+
31+
for _, job := range jobs {
32+
// If the job is set to run immediately, run it now.
33+
if job.RunNow {
34+
err := job.Run(c.cmd)
35+
if err != nil {
36+
slog.Error("error running job",
37+
"error", err.Error(),
38+
)
39+
}
40+
}
41+
42+
// Start the job in a goroutine that runs on the specified interval.
43+
wg.Add(1)
44+
go func(j Job) {
45+
defer wg.Done()
46+
47+
ticker := time.NewTicker(j.Interval)
48+
defer ticker.Stop()
49+
50+
for {
51+
select {
52+
case <-ctx.Done():
53+
return
54+
case <-ticker.C:
55+
err := j.Run(c.cmd)
56+
if err != nil {
57+
slog.Error("error running job",
58+
"error", err.Error(),
59+
)
60+
}
61+
}
62+
}
63+
}(job)
64+
}
65+
66+
// Block until all jobs are done.
67+
wg.Wait()
68+
return nil
69+
}

0 commit comments

Comments
 (0)