frostfs-qos/scheduling/clock.go
Dmitrii Stepanov 47559a8d16
[] mclock: Refactor: split code between files
Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
2025-01-28 11:20:53 +03:00

81 lines
1.1 KiB
Go

package scheduling
import (
"sync"
"time"
)
type clock interface {
now() float64
runAt(ts float64, f func())
close()
}
type scheduleInfo struct {
ts float64
f func()
}
type systemClock struct {
since time.Time
schedule chan scheduleInfo
wg sync.WaitGroup
}
func newSystemClock() *systemClock {
c := &systemClock{
since: time.Now(),
schedule: make(chan scheduleInfo),
}
c.start()
return c
}
func (c *systemClock) now() float64 {
return time.Since(c.since).Seconds()
}
func (c *systemClock) runAt(ts float64, f func()) {
c.schedule <- scheduleInfo{ts: ts, f: f}
}
func (c *systemClock) close() {
close(c.schedule)
c.wg.Wait()
}
func (c *systemClock) start() {
c.wg.Add(1)
go func() {
defer c.wg.Done()
t := time.NewTimer(time.Hour)
var f func()
for {
select {
case <-t.C:
if f != nil {
f()
f = nil
}
case s, ok := <-c.schedule:
if !ok {
return
}
now := c.now()
if now >= s.ts {
s.f()
f = nil
continue
}
if !t.Stop() {
select {
case <-t.C:
default:
}
}
t.Reset(time.Duration((s.ts - now) * 1e9))
f = s.f
}
}
}()
}