Skip to content

Instantly share code, notes, and snippets.

@emrekasg
Created January 10, 2024 14:58
Show Gist options
  • Save emrekasg/85b89c1d988503b9cecfa95ec4f9da49 to your computer and use it in GitHub Desktop.
Save emrekasg/85b89c1d988503b9cecfa95ec4f9da49 to your computer and use it in GitHub Desktop.
sleepWorkers.go
package workers
import (
"context"
"fmt"
"sync"
"time"
)
// WorkerElement represents information about a worker.
type WorkerElement struct {
Name string `json:"name"`
Duration time.Duration `json:"duration"`
}
var (
workers = make(map[string]*workerContext)
workersList []WorkerElement
mu sync.Mutex
)
type workerContext struct {
ctx context.Context
cancel context.CancelFunc
workerFn func()
waitGroup sync.WaitGroup
}
// Register adds a worker function.
func Register(name string, handler func(x interface{})) {
worker := &workerContext{
ctx: context.Background(),
}
worker.start(name, handler)
}
// RegisterPeriodically adds a worker function that runs periodically.
func RegisterPeriodically(name string, duration time.Duration, handler func(x interface{})) {
worker := &workerContext{
ctx: context.Background(),
}
worker.startPeriodic(name, duration, handler)
}
// Stop stops a worker by name.
func Stop(name string) {
mu.Lock()
defer mu.Unlock()
if worker, ok := workers[name]; ok {
worker.cancel()
delete(workers, name)
fmt.Println("Stopping worker:", name)
} else {
fmt.Println("Worker not found:", name)
}
}
// Run starts all registered workers and runs indefinitely.
func Run() {
for {
select {}
}
}
func (w *workerContext) start(name string, handler func(x interface{})) {
w.workerFn = func() {
for {
handler(nil)
}
}
w.startWorker(name)
}
func (w *workerContext) startPeriodic(name string, duration time.Duration, handler func(x interface{})) {
w.workerFn = func() {
for {
handler(nil)
fmt.Println("Periodic worker:", name, "sleeping for", duration)
select {
case <-w.ctx.Done():
return
case <-time.After(duration):
}
}
}
w.startWorker(name)
}
func (w *workerContext) startWorker(name string) {
mu.Lock()
workers[name] = w
mu.Unlock()
w.waitGroup.Add(1)
go func() {
defer w.waitGroup.Done()
w.workerFn()
}()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment