Skip to content

Instantly share code, notes, and snippets.

@kubosuke
Last active October 22, 2024 13:20
Show Gist options
  • Save kubosuke/8c67721d3605055bc59ec6b52ced3a2b to your computer and use it in GitHub Desktop.
Save kubosuke/8c67721d3605055bc59ec6b52ced3a2b to your computer and use it in GitHub Desktop.
Go sequential cronjob sample
package main
import (
"fmt"
"log"
"os"
"os/signal"
"sync"
"syscall"
"time"
)
type Job interface {
Execute()
}
type JobQueue struct {
jobs chan Job
wg sync.WaitGroup
quit chan bool
closed bool
mu sync.Mutex
}
func NewJobQueue() *JobQueue {
jq := &JobQueue{
jobs: make(chan Job),
quit: make(chan bool),
}
jq.wg.Add(1)
go jq.worker()
return jq
}
func (jq *JobQueue) Enqueue(job Job) {
jq.mu.Lock()
defer jq.mu.Unlock()
if jq.closed {
log.Println("Attempt to enqueue on closed queue")
return
}
jq.jobs <- job
}
func (jq *JobQueue) worker() {
defer jq.wg.Done()
for {
select {
case job := <-jq.jobs:
job.Execute()
case <-jq.quit:
return
}
}
}
func (jq *JobQueue) Close() {
jq.mu.Lock()
if !jq.closed {
jq.closed = true
close(jq.quit)
jq.wg.Wait()
close(jq.jobs)
}
jq.mu.Unlock()
}
type ExampleJob struct {
ID string
DateTime time.Time
}
func NewExampleJob() ExampleJob {
return ExampleJob{
ID: generateShortUUID(),
DateTime: time.Now(),
}
}
func generateShortUUID() string {
return fmt.Sprintf("%x", time.Now().UnixNano())
}
func (e ExampleJob) Execute() {
fmt.Printf("🚀 Enqueued job %s at %s, execution started at %s\n", e.ID, e.DateTime.Format(time.RFC3339), time.Now().Format(time.RFC3339))
time.Sleep(5 * time.Second)
fmt.Printf("✅ Job %s done\n", e.ID)
}
func main() {
jq := NewJobQueue()
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
ticker := time.NewTicker(5 * time.Second)
done := make(chan bool, 1)
go func() {
for {
select {
case <-ticker.C:
for i := 0; i < 5; i++ {
go jq.Enqueue(NewExampleJob())
}
case sig := <-sigChan:
fmt.Printf("⚠️ Received signal: %s. Initiating graceful shutdown.\n", sig)
ticker.Stop()
done <- true
return
}
}
}()
<-done
fmt.Println("🛑 Server process has been gracefully shut down.")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment