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  }