Select Git revision
-
Volker Schukai authoredVolker Schukai authored
hash_watcher.go 1.63 KiB
// Copyright 2024 schukai GmbH
// SPDX-License-Identifier: proprietary
package watch
import (
"context"
"sync"
"time"
)
type Watcher struct {
cache sync.Map
mutex sync.Mutex
cancel context.CancelFunc
active bool
}
// NewWatcher creates a new Watcher.
// This Function starts a goroutine that checks the cache every hour and removes expired entries.
// It is in your responsibility to call Stop() on the Watcher, after you are done with it.
func NewWatcher() *Watcher {
ctx, cancel := context.WithCancel(context.Background())
w := &Watcher{
cache: sync.Map{},
cancel: cancel,
mutex: sync.Mutex{},
active: true,
}
go w.cacheCleaner(ctx)
return w
}
// Stop stops the cleaner goroutine.
func (w *Watcher) Stop() {
w.cancel()
}
// IsActive returns true if the watcher is active, false if not.
// An not active watcher can not be used to add, remove or check files.
func (w *Watcher) IsActive() bool {
w.mutex.Lock()
defer w.mutex.Unlock()
return w.active
}
func (w *Watcher) setActive() {
w.mutex.Lock()
defer w.mutex.Unlock()
w.active = true
}
func (w *Watcher) setInactive() {
w.mutex.Lock()
defer w.mutex.Unlock()
w.active = false
}
// cacheCleaner is a goroutine that checks the cache every hour and removes expired entries.
func (w *Watcher) cacheCleaner(ctx context.Context) {
ticker := time.NewTicker(1 * time.Hour)
defer ticker.Stop()
for {
select {
case <-ticker.C:
now := time.Now()
w.cache.Range(func(key, value interface{}) bool {
hash := value.(FileHash)
if hash.expiresAt.Before(now) {
w.cache.Delete(key)
}
return true
})
case <-ctx.Done():
w.setInactive()
return
}
}
}