feat: complete remaining Go backend modules
This commit is contained in:
1 parent
cea2751dc5
commit
aef5a97165
145 files changed
+18376
-199
No files matched your search
@@ -0,0 +1,80 @@
|
||||
package jobs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
type TickRunner interface {
|
||||
Tick(context.Context, string) (TickResult, error)
|
||||
}
|
||||
type LoopConfig struct {
|
||||
Interval time.Duration
|
||||
WorkerID string
|
||||
}
|
||||
type WorkerLoop struct {
|
||||
runner TickRunner
|
||||
config LoopConfig
|
||||
running atomic.Bool
|
||||
mu sync.Mutex
|
||||
cancel context.CancelFunc
|
||||
done chan struct{}
|
||||
}
|
||||
|
||||
func NewWorkerLoop(r TickRunner, c LoopConfig) *WorkerLoop {
|
||||
if c.Interval <= 0 {
|
||||
c.Interval = 5 * time.Second
|
||||
}
|
||||
if c.WorkerID == "" {
|
||||
c.WorkerID = "embedded-worker"
|
||||
}
|
||||
return &WorkerLoop{runner: r, config: c}
|
||||
}
|
||||
func (l *WorkerLoop) Tick(ctx context.Context) (TickResult, bool) {
|
||||
if l == nil || l.runner == nil || !l.running.CompareAndSwap(false, true) {
|
||||
return TickResult{}, false
|
||||
}
|
||||
defer l.running.Store(false)
|
||||
r, e := l.runner.Tick(ctx, l.config.WorkerID)
|
||||
if e != nil {
|
||||
return TickResult{WorkerID: l.config.WorkerID, Jobs: []TickJob{{Action: "failed", Error: e.Error()}}}, true
|
||||
}
|
||||
return r, true
|
||||
}
|
||||
func (l *WorkerLoop) Start(parent context.Context) {
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
if l.cancel != nil {
|
||||
return
|
||||
}
|
||||
ctx, cancel := context.WithCancel(parent)
|
||||
l.cancel = cancel
|
||||
l.done = make(chan struct{})
|
||||
go func() {
|
||||
defer close(l.done)
|
||||
ticker := time.NewTicker(l.config.Interval)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
_, _ = l.Tick(ctx)
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-ticker.C:
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
func (l *WorkerLoop) Stop() {
|
||||
l.mu.Lock()
|
||||
cancel, done := l.cancel, l.done
|
||||
l.cancel = nil
|
||||
l.done = nil
|
||||
l.mu.Unlock()
|
||||
if cancel == nil {
|
||||
return
|
||||
}
|
||||
cancel()
|
||||
<-done
|
||||
}
|
||||
Reference in new issue
Block a user