mirror of
https://github.com/Luzifer/twitch-bot.git
synced 2024-12-20 20:01:17 +00:00
Fix: Concurrent access to map panic
Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
parent
b7538d9b93
commit
8b575f7771
2 changed files with 24 additions and 8 deletions
|
@ -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(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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, ":"))
|
||||||
|
|
Loading…
Reference in a new issue