github.com/safing/portbase@v0.19.5/modules/sleepyticker.go (about) 1 package modules 2 3 import "time" 4 5 // SleepyTicker is wrapper over time.Ticker that respects the sleep mode of the module. 6 type SleepyTicker struct { 7 ticker time.Ticker 8 module *Module 9 normalDuration time.Duration 10 sleepDuration time.Duration 11 sleepMode bool 12 } 13 14 // newSleepyTicker returns a new SleepyTicker. This is a wrapper of the standard time.Ticker but it respects modules.Module sleep mode. Check https://pkg.go.dev/time#Ticker. 15 // If sleepDuration is set to 0 ticker will not tick during sleep. 16 func newSleepyTicker(module *Module, normalDuration time.Duration, sleepDuration time.Duration) *SleepyTicker { 17 st := &SleepyTicker{ 18 ticker: *time.NewTicker(normalDuration), 19 module: module, 20 normalDuration: normalDuration, 21 sleepDuration: sleepDuration, 22 sleepMode: false, 23 } 24 25 return st 26 } 27 28 // Wait waits until the module is not in sleep mode and returns time.Ticker.C channel. 29 func (st *SleepyTicker) Wait() <-chan time.Time { 30 sleepModeEnabled := st.module.sleepMode.IsSet() 31 32 // Update Sleep mode 33 if sleepModeEnabled != st.sleepMode { 34 st.enterSleepMode(sleepModeEnabled) 35 } 36 37 // Wait if until sleep mode exits only if sleepDuration is set to 0. 38 if sleepModeEnabled && st.sleepDuration == 0 { 39 return st.module.WaitIfSleeping() 40 } 41 42 return st.ticker.C 43 } 44 45 // Stop turns off a ticker. After Stop, no more ticks will be sent. Stop does not close the channel, to prevent a concurrent goroutine reading from the channel from seeing an erroneous "tick". 46 func (st *SleepyTicker) Stop() { 47 st.ticker.Stop() 48 } 49 50 func (st *SleepyTicker) enterSleepMode(enabled bool) { 51 st.sleepMode = enabled 52 if enabled { 53 if st.sleepDuration > 0 { 54 st.ticker.Reset(st.sleepDuration) 55 } 56 } else { 57 st.ticker.Reset(st.normalDuration) 58 } 59 }