Created
January 10, 2024 14:58
-
-
Save emrekasg/85b89c1d988503b9cecfa95ec4f9da49 to your computer and use it in GitHub Desktop.
sleepWorkers.go
This file contains hidden or 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
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