package timeout
import (
"sync"
"time"
)
type Timeout struct {
timeouts map[string]time.Time
mutex sync.RWMutex
}
func New() Timeout {
return Timeout{
timeouts: make(map[string]time.Time),
}
}
func (to *Timeout) SetTimeout(key string, duration time.Duration) {
now := time.Now()
to.mutex.Lock()
to.timeouts[key] = now.Add(duration)
to.mutex.Unlock()
}
func (to *Timeout) CheckTimeout(key string) bool {
now := time.Now()
to.mutex.RLock()
timeout, ok := to.timeouts[key]
to.mutex.RUnlock()
val := ok && (now.Before(timeout) || now.Equal(timeout))
if !val {
to.RemoveTimeout(key)
}
return val
}
func (to *Timeout) RemoveTimeout(key string) {
to.mutex.Lock()
delete(to.timeouts, key)
to.mutex.Unlock()
}
func (to *Timeout) Timeouts() map[string]time.Time {
to.PruneTimeouts()
copy := make(map[string]time.Time, len(to.timeouts))
for key, val := range to.timeouts {
copy[key] = val
}
return copy
}
func (to *Timeout) PruneTimeouts() []string {
now := time.Now()
var handles []string
for key, timeout := range to.timeouts {
if now.After(timeout) {
handles = append(handles, key)
to.RemoveTimeout(key)
}
}
return handles
}