Fixes #23: Race condition with maps and goroutines

Signed-off-by: David Randall <David@NiceGuyIT.biz>
This commit is contained in:
David Randall 2022-11-05 08:45:48 -04:00
parent 9bc77c579d
commit 18b5b8d57e
1 changed files with 12 additions and 7 deletions

View File

@ -18,6 +18,7 @@ import (
"io/ioutil" "io/ioutil"
"os/exec" "os/exec"
"strings" "strings"
"sync"
"time" "time"
"github.com/go-kit/log" "github.com/go-kit/log"
@ -32,11 +33,11 @@ type JSONCache struct {
} }
var ( var (
jsonCache map[string]JSONCache jsonCache sync.Map
) )
func init() { func init() {
jsonCache = make(map[string]JSONCache) jsonCache.Store("", JSONCache{})
} }
// Parse json to gjson object // Parse json to gjson object
@ -93,16 +94,20 @@ func readData(logger log.Logger, device string) (gjson.Result, error) {
return readFakeSMARTctl(logger, device), nil return readFakeSMARTctl(logger, device), nil
} }
cacheValue, cacheOk := jsonCache[device] cacheValue, cacheOk := jsonCache.Load(device)
if !cacheOk || time.Now().After(cacheValue.LastCollect.Add(*smartctlInterval)) { if !cacheOk || time.Now().After(cacheValue.(JSONCache).LastCollect.Add(*smartctlInterval)) {
json, ok := readSMARTctl(logger, device) json, ok := readSMARTctl(logger, device)
if ok { if ok {
jsonCache[device] = JSONCache{JSON: json, LastCollect: time.Now()} jsonCache.Store(device, JSONCache{JSON: json, LastCollect: time.Now()})
return jsonCache[device].JSON, nil j, found := jsonCache.Load(device)
if !found {
level.Warn(logger).Log("msg", "device not found", "device", device)
}
return j.(JSONCache).JSON, nil
} }
return gjson.Parse("{}"), fmt.Errorf("smartctl returned bad data for device %s", device) return gjson.Parse("{}"), fmt.Errorf("smartctl returned bad data for device %s", device)
} }
return cacheValue.JSON, nil return cacheValue.(JSONCache).JSON, nil
} }
// Parse smartctl return code // Parse smartctl return code