hackathon/db/cooldown.go

68 lines
1.1 KiB
Go

package db
import (
"sync"
"time"
)
type CooldownEntry struct {
UserID string
QuestionID string
}
type Cooldowns struct {
m map[CooldownEntry]time.Time
mu *sync.Mutex
}
func NewCooldowns() Cooldowns {
c := make(map[CooldownEntry]time.Time)
mu := &sync.Mutex{}
go func() {
for {
mu.Lock()
now := time.Now()
for k, v := range c {
if now.After(v) {
delete(c, k)
}
}
mu.Unlock()
time.Sleep(time.Minute * 5)
}
}()
return Cooldowns{c, mu}
}
func (c Cooldowns) NewAttempt(userID string, questionID string, attempts int) {
c.mu.Lock()
defer c.mu.Unlock()
var timeout time.Duration
switch attempts {
case 0:
timeout = time.Minute
case 1:
timeout = time.Minute * 3 / 2 // 90 seconds
case 2:
timeout = time.Minute * 3
default:
timeout = time.Minute * 5
}
c.m[CooldownEntry{userID, questionID}] = time.Now().Add(timeout)
}
func (c Cooldowns) Check(userID string, questionID string) time.Duration {
c.mu.Lock()
defer c.mu.Unlock()
expires, ok := c.m[CooldownEntry{userID, questionID}]
now := time.Now()
if !ok || now.After(expires) {
return 0
}
return expires.Sub(now)
}