Fix: Concurrent access to map panic

Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
Knut Ahlers 2021-04-01 12:28:51 +02:00
parent b7538d9b93
commit 8b575f7771
Signed by: luzifer
GPG key ID: 0066F03ED215AD7D
2 changed files with 24 additions and 8 deletions

View file

@ -15,12 +15,12 @@ import (
var twitch = newTwitchClient() var twitch = newTwitchClient()
type twitchClient struct { type twitchClient struct {
apiCache twitchAPICache apiCache *twitchAPICache
} }
func newTwitchClient() *twitchClient { func newTwitchClient() *twitchClient {
return &twitchClient{ return &twitchClient{
apiCache: make(twitchAPICache), apiCache: newTwitchAPICache(),
} }
} }

View file

@ -4,19 +4,32 @@ import (
"crypto/sha256" "crypto/sha256"
"fmt" "fmt"
"strings" "strings"
"sync"
"time" "time"
) )
type ( type (
twitchAPICache map[string]twitchAPICacheEntry twitchAPICache struct {
data map[string]twitchAPICacheEntry
lock sync.RWMutex
}
twitchAPICacheEntry struct { twitchAPICacheEntry struct {
Data interface{} Data interface{}
ValidUntil time.Time ValidUntil time.Time
} }
) )
func (t twitchAPICache) Get(key []string) interface{} { func newTwitchAPICache() *twitchAPICache {
e := t[t.deriveKey(key)] return &twitchAPICache{
data: make(map[string]twitchAPICacheEntry),
}
}
func (t *twitchAPICache) Get(key []string) interface{} {
t.lock.RLock()
defer t.lock.RUnlock()
e := t.data[t.deriveKey(key)]
if e.ValidUntil.Before(time.Now()) { if e.ValidUntil.Before(time.Now()) {
return nil return nil
} }
@ -24,14 +37,17 @@ func (t twitchAPICache) Get(key []string) interface{} {
return e.Data return e.Data
} }
func (t twitchAPICache) Set(key []string, valid time.Duration, data interface{}) { func (t *twitchAPICache) Set(key []string, valid time.Duration, data interface{}) {
t[t.deriveKey(key)] = twitchAPICacheEntry{ t.lock.Lock()
defer t.lock.Unlock()
t.data[t.deriveKey(key)] = twitchAPICacheEntry{
Data: data, Data: data,
ValidUntil: time.Now().Add(valid), ValidUntil: time.Now().Add(valid),
} }
} }
func (twitchAPICache) deriveKey(key []string) string { func (*twitchAPICache) deriveKey(key []string) string {
sha := sha256.New() sha := sha256.New()
fmt.Fprintf(sha, "%s", strings.Join(key, ":")) fmt.Fprintf(sha, "%s", strings.Join(key, ":"))