time.go 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. package utils
  2. import (
  3. "sync"
  4. "sync/atomic"
  5. "time"
  6. )
  7. var (
  8. timestamp uint32
  9. updaterOnce sync.Once
  10. stopUpdater chan struct{}
  11. updaterDone chan struct{}
  12. )
  13. // Timestamp returns the current cached Unix timestamp (seconds).
  14. // Call StartTimeStampUpdater() once at app startup for best performance.
  15. func Timestamp() uint32 {
  16. return atomic.LoadUint32(&timestamp)
  17. }
  18. // StartTimeStampUpdater launches a background goroutine that updates the cached timestamp every second.
  19. // It is safe to call multiple times; only the first call will start the updater.
  20. func StartTimeStampUpdater() {
  21. updaterOnce.Do(func() {
  22. atomic.StoreUint32(&timestamp, uint32(time.Now().Unix()))
  23. stopUpdater = make(chan struct{})
  24. updaterDone = make(chan struct{})
  25. go func() {
  26. ticker := time.NewTicker(time.Second)
  27. defer ticker.Stop()
  28. defer close(updaterDone)
  29. for {
  30. select {
  31. case <-ticker.C:
  32. atomic.StoreUint32(&timestamp, uint32(time.Now().Unix()))
  33. case <-stopUpdater:
  34. return
  35. }
  36. }
  37. }()
  38. })
  39. }
  40. // StopTimeStampUpdater stops the background updater goroutine.
  41. // Call this on app shutdown to avoid leaking goroutines.
  42. func StopTimeStampUpdater() {
  43. if stopUpdater != nil {
  44. close(stopUpdater)
  45. <-updaterDone
  46. // Reset the sync.Once so StartTimeStampUpdater can be called again
  47. updaterOnce = sync.Once{}
  48. stopUpdater = nil
  49. updaterDone = nil
  50. }
  51. }