This commit is contained in:
Caleb Doxsey 2024-04-19 15:39:34 -06:00
parent a80ef11763
commit 2eaa4291ae
3 changed files with 72 additions and 10 deletions

View file

@ -162,7 +162,7 @@ func (mgr *Manager) onUpdateUser(ctx context.Context, u *user.User) {
mgr.dataStore.putUser(u)
_, ok := mgr.updateUserInfoSchedulers[u.GetId()]
if !ok {
uuis := newUpdateUserInfoScheduler(ctx, mgr, u.GetId())
uuis := newUpdateUserInfoScheduler(ctx, mgr.cfg.Load().updateUserInfoInterval, mgr.updateUserInfo, u.GetId())
mgr.updateUserInfoSchedulers[u.GetId()] = uuis
}
mgr.mu.Unlock()

View file

@ -9,17 +9,25 @@ import (
)
type updateUserInfoScheduler struct {
mgr *Manager
userID string
updateUserInfoInterval time.Duration
updateUserInfo func(ctx context.Context, userID string)
userID string
reset chan struct{}
cancel context.CancelFunc
}
func newUpdateUserInfoScheduler(ctx context.Context, mgr *Manager, userID string) *updateUserInfoScheduler {
func newUpdateUserInfoScheduler(
ctx context.Context,
updateUserInfoInterval time.Duration,
updateUserInfo func(ctx context.Context, userID string),
userID string,
) *updateUserInfoScheduler {
uuis := &updateUserInfoScheduler{
mgr: mgr,
userID: userID,
reset: make(chan struct{}, 1),
updateUserInfoInterval: updateUserInfoInterval,
updateUserInfo: updateUserInfo,
userID: userID,
reset: make(chan struct{}, 1),
}
ctx = context.WithoutCancel(ctx)
ctx, uuis.cancel = context.WithCancel(ctx)
@ -39,7 +47,7 @@ func (uuis *updateUserInfoScheduler) Stop() {
}
func (uuis *updateUserInfoScheduler) run(ctx context.Context) {
ticker := time.NewTicker(uuis.mgr.cfg.Load().updateUserInfoInterval)
ticker := time.NewTicker(uuis.updateUserInfoInterval)
defer ticker.Stop()
for {
@ -47,9 +55,9 @@ func (uuis *updateUserInfoScheduler) run(ctx context.Context) {
case <-ctx.Done():
return
case <-uuis.reset:
ticker.Reset(uuis.mgr.cfg.Load().updateUserInfoInterval)
ticker.Reset(uuis.updateUserInfoInterval)
case <-ticker.C:
uuis.mgr.updateUserInfo(ctx, uuis.userID)
uuis.updateUserInfo(ctx, uuis.userID)
}
}
}

View file

@ -0,0 +1,54 @@
package manager
import (
"context"
"sync"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestUpdateUserInfoScheduler(t *testing.T) {
t.Parallel()
var mu sync.Mutex
var calls []time.Time
ctx := context.Background()
userUpdateInfoInterval := 100 * time.Millisecond
uuis := newUpdateUserInfoScheduler(ctx, userUpdateInfoInterval, func(ctx context.Context, userID string) {
mu.Lock()
calls = append(calls, time.Now())
mu.Unlock()
}, "U1")
t.Cleanup(uuis.Stop)
// should eventually trigger
assert.Eventually(t, func() bool {
mu.Lock()
n := len(calls)
mu.Unlock()
return n == 1
}, 3*userUpdateInfoInterval, userUpdateInfoInterval/10, "should trigger once")
uuis.Reset()
uuis.Reset()
uuis.Reset()
assert.Eventually(t, func() bool {
mu.Lock()
n := len(calls)
mu.Unlock()
return n == 2
}, 3*userUpdateInfoInterval, userUpdateInfoInterval/10, "should trigger once after multiple resets")
mu.Lock()
var diff time.Duration
if len(calls) >= 2 {
diff = calls[len(calls)-1].Sub(calls[len(calls)-2])
}
mu.Unlock()
assert.GreaterOrEqual(t, diff, userUpdateInfoInterval, "delay should exceed interval")
}