Skip to content

Instantly share code, notes, and snippets.

@nhocki
Last active December 2, 2023 11:38
Show Gist options
  • Save nhocki/a7e5c55ff4387020eac3 to your computer and use it in GitHub Desktop.
Save nhocki/a7e5c55ff4387020eac3 to your computer and use it in GitHub Desktop.
Simple task scheduling with Redis & Go. Similar to Sidekiq's `perform_in` and `perform_at`.
// poller.go
package main
import (
"fmt"
"os"
"os/signal"
"time"
"github.com/fzzy/radix/redis"
)
var redisConn *redis.Client
func init() {
var err error
if redisConn, err = redis.Dial("tcp", "127.0.0.1:6379"); err != nil {
panic(err)
}
}
// Poll checks Redis to determine whether scheduled tasks need to be run or not.
func Poll(interval time.Duration, done <-chan os.Signal) {
ticker := time.NewTicker(interval)
for {
select {
case <-ticker.C:
fmt.Print("> Checking for scheduled tasks... ")
nowUnix := time.Now().Unix()
response := redisConn.Cmd("ZRANGEBYSCORE", "jobs:scheduled", "-inf", float64(nowUnix))
tasks, _ := response.List()
if len(tasks) == 0 {
fmt.Println("No tasks found.")
}
for _, task := range tasks {
fmt.Printf("Queue task: %s\n", task)
redisConn.Cmd("ZREM", "jobs:scheduled", task)
}
case <-done:
fmt.Println("Shutting down poller")
return
}
}
}
func main() {
c := make(chan os.Signal)
signal.Notify(c, os.Interrupt)
fmt.Println("Polling Redis every 15 seconds for scheduled tasks...")
Poll(15 * time.Second, c)
}
// scheduler.go
package main
import (
"fmt"
"os"
"os/signal"
"time"
"github.com/fzzy/radix/redis"
)
var redisConn *redis.Client
func init() {
var err error
if redisConn, err = redis.Dial("tcp", "127.0.0.1:6379"); err != nil {
panic(err)
}
}
// PerformIn schedules a given task to be executed in the given duration.
func PerformIn(in time.Duration, task string) {
at := time.Now().Add(in)
PerformAt(at, task)
}
// PerformAt schedules a task to be executed at a given time.
func PerformAt(at time.Time, task string) {
fmt.Printf("> Scheduling %s with score %d\n", task, at.Unix())
redisConn.Cmd("zadd", "jobs:scheduled", float64(at.Unix()), task)
}
func main() {
at, _ := time.Parse("2006-Jan-02", "2016-Jan-01")
PerformAt(at, "Happy New Year!")
PerformIn(2 * time.Minute, "Snooze wakeup alarm!")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment