Last active
December 2, 2023 11:38
-
-
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`.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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