github.com/webmafia/fast@v0.10.0/clock.go (about) 1 package fast 2 3 import ( 4 "context" 5 "sync/atomic" 6 "time" 7 ) 8 9 type Clock struct { 10 ts int64 11 } 12 13 func NewClock(ctx context.Context) *Clock { 14 c := &Clock{ 15 ts: time.Now().Unix(), 16 } 17 18 go c.tick(ctx) 19 20 return c 21 } 22 23 //go:inline 24 func (c *Clock) Now() time.Time { 25 return time.Unix(c.Unix(), 0) 26 } 27 28 //go:inline 29 func (c *Clock) Unix() int64 { 30 return atomic.LoadInt64(&c.ts) 31 } 32 33 func (c *Clock) tick(ctx context.Context) { 34 ticker := time.NewTicker(time.Second) 35 now := time.Now() 36 37 // Wait to the next second 38 nextSec := now.Truncate(time.Second).Add(time.Second) 39 delay := nextSec.Sub(now) 40 41 if delay > 0 { 42 ticker.Reset(delay) 43 <-ticker.C 44 ticker.Reset(time.Second) 45 } 46 47 for { 48 select { 49 case <-ctx.Done(): 50 return 51 case ts := <-ticker.C: 52 atomic.StoreInt64(&c.ts, ts.Unix()) 53 } 54 } 55 }