mirror of
https://github.com/ChuckNorrison/LightningTipBot.git
synced 2026-08-14 12:43:14 +02:00
77 lines
1.7 KiB
Go
77 lines
1.7 KiB
Go
|
|
package runtime
|
||
|
|
|
||
|
|
import (
|
||
|
|
cmap "github.com/orcaman/concurrent-map"
|
||
|
|
"time"
|
||
|
|
)
|
||
|
|
|
||
|
|
var tickerMap cmap.ConcurrentMap
|
||
|
|
|
||
|
|
func init() {
|
||
|
|
tickerMap = cmap.New()
|
||
|
|
}
|
||
|
|
|
||
|
|
var defaultTickerCoolDown = time.Second * 10
|
||
|
|
|
||
|
|
// ResettableFunctionTicker will reset the user state as soon as tick is delivered.
|
||
|
|
type ResettableFunctionTicker struct {
|
||
|
|
Ticker *time.Ticker
|
||
|
|
ResetChan chan struct{} // channel used to reset the ticker
|
||
|
|
duration time.Duration
|
||
|
|
Started bool
|
||
|
|
name string
|
||
|
|
}
|
||
|
|
type ResettableFunctionTickerOption func(*ResettableFunctionTicker)
|
||
|
|
|
||
|
|
func WithDuration(d time.Duration) ResettableFunctionTickerOption {
|
||
|
|
return func(a *ResettableFunctionTicker) {
|
||
|
|
a.duration = d
|
||
|
|
}
|
||
|
|
}
|
||
|
|
func RemoveTicker(name string) {
|
||
|
|
tickerMap.Remove(name)
|
||
|
|
}
|
||
|
|
func GetTicker(name string, option ...ResettableFunctionTickerOption) *ResettableFunctionTicker {
|
||
|
|
|
||
|
|
if t, ok := tickerMap.Get(name); ok {
|
||
|
|
return t.(*ResettableFunctionTicker)
|
||
|
|
} else {
|
||
|
|
t := NewResettableFunctionTicker(name, option...)
|
||
|
|
tickerMap.Set(name, t)
|
||
|
|
return t
|
||
|
|
}
|
||
|
|
}
|
||
|
|
func NewResettableFunctionTicker(name string, option ...ResettableFunctionTickerOption) *ResettableFunctionTicker {
|
||
|
|
t := &ResettableFunctionTicker{
|
||
|
|
ResetChan: make(chan struct{}, 1),
|
||
|
|
name: name,
|
||
|
|
}
|
||
|
|
|
||
|
|
for _, opt := range option {
|
||
|
|
opt(t)
|
||
|
|
}
|
||
|
|
if t.duration == 0 {
|
||
|
|
t.duration = defaultTickerCoolDown
|
||
|
|
}
|
||
|
|
t.Ticker = time.NewTicker(t.duration)
|
||
|
|
return t
|
||
|
|
}
|
||
|
|
|
||
|
|
func (t *ResettableFunctionTicker) Do(f func()) {
|
||
|
|
t.Started = true
|
||
|
|
tickerMap.Set(t.name, t)
|
||
|
|
go func() {
|
||
|
|
for {
|
||
|
|
select {
|
||
|
|
case <-t.Ticker.C:
|
||
|
|
// ticker delivered signal. do function f
|
||
|
|
f()
|
||
|
|
return
|
||
|
|
case <-t.ResetChan:
|
||
|
|
// reset signal received. creating new ticker.
|
||
|
|
t.Ticker = time.NewTicker(t.duration)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}()
|
||
|
|
}
|