74 lines
1.6 KiB
Go
74 lines
1.6 KiB
Go
package cleaners
|
|
|
|
import (
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
type CleanerManager struct {
|
|
activeCleaners map[string]bool
|
|
activeCleanerLock sync.Mutex
|
|
exitChans []chan any
|
|
}
|
|
|
|
var cleanerBuilders = []func() (onTick func(time.Time), name string, tickSpeed time.Duration){}
|
|
|
|
func NewManager() *CleanerManager {
|
|
activeCleaners := make(map[string]bool)
|
|
exitChans := []chan any{}
|
|
cm := &CleanerManager{
|
|
activeCleaners: activeCleaners,
|
|
exitChans: exitChans,
|
|
}
|
|
|
|
// Launch all cleaner tickers in a new goroutine each
|
|
for _, builder := range cleanerBuilders {
|
|
exitChan := make(chan any, 1)
|
|
onTick, name, tickSpeed := builder()
|
|
cm.exitChans = append(cm.exitChans, exitChan)
|
|
log.Info().Str("name", name).Msg("Starting ticker for cleaner")
|
|
go cm.tickOrExit(tickSpeed, name, exitChan, onTick)
|
|
}
|
|
|
|
return cm
|
|
}
|
|
|
|
func (m *CleanerManager) Stop() {
|
|
for _, exitChan := range m.exitChans {
|
|
exitChan <- 1
|
|
}
|
|
}
|
|
|
|
func (m *CleanerManager) tickOrExit(
|
|
tickSpeed time.Duration,
|
|
name string,
|
|
exitChan chan any,
|
|
onTick func(time.Time),
|
|
) {
|
|
ticker := time.Tick(tickSpeed)
|
|
for {
|
|
select {
|
|
case now := <-ticker:
|
|
go m.wrapOnTick(name, now, onTick)
|
|
case <-exitChan:
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
func (m *CleanerManager) wrapOnTick(name string, now time.Time, onTick func(time.Time)) {
|
|
m.activeCleanerLock.Lock()
|
|
if m.activeCleaners[name] {
|
|
m.activeCleanerLock.Unlock()
|
|
return
|
|
}
|
|
m.activeCleaners[name] = true
|
|
m.activeCleanerLock.Unlock()
|
|
log.Info().Str("cleaner", name).Msg("Ticking cleaner")
|
|
onTick(now)
|
|
m.activeCleanerLock.Lock()
|
|
m.activeCleaners[name] = false
|
|
m.activeCleanerLock.Unlock()
|
|
}
|