chore: reduce database writes (#24672)
This commit is contained in:
parent
001b23ce95
commit
8e9961ef5a
1 changed files with 21 additions and 14 deletions
|
|
@ -11,11 +11,11 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/evcc-io/evcc/server/db"
|
||||
"github.com/evcc-io/evcc/util"
|
||||
"github.com/samber/lo"
|
||||
"go.yaml.in/yaml/v4"
|
||||
)
|
||||
|
||||
|
|
@ -23,6 +23,7 @@ var ErrNotFound = errors.New("not found")
|
|||
|
||||
// setting is a settings entry
|
||||
type setting struct {
|
||||
dirty bool
|
||||
Key string `json:"key" gorm:"primarykey"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
|
@ -30,7 +31,6 @@ type setting struct {
|
|||
var (
|
||||
mu sync.RWMutex
|
||||
settings []setting
|
||||
dirty int32
|
||||
)
|
||||
|
||||
func Init() error {
|
||||
|
|
@ -42,12 +42,22 @@ func Init() error {
|
|||
}
|
||||
|
||||
func Persist() error {
|
||||
dirty := atomic.CompareAndSwapInt32(&dirty, 1, 0)
|
||||
if !dirty || len(settings) == 0 {
|
||||
// avoid "empty slice found"
|
||||
return nil
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
|
||||
if dirty := lo.FilterMap(settings, func(s setting, _ int) (*setting, bool) {
|
||||
return &s, s.dirty
|
||||
}); len(dirty) > 0 {
|
||||
if err := db.Instance.Save(dirty).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, s := range dirty {
|
||||
s.dirty = false
|
||||
}
|
||||
}
|
||||
return db.Instance.Save(settings).Error
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func All() []setting {
|
||||
|
|
@ -88,14 +98,11 @@ func SetString(key string, val string) {
|
|||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
|
||||
idx := slices.IndexFunc(settings, equal(key))
|
||||
|
||||
if idx < 0 {
|
||||
settings = append(settings, setting{key, val})
|
||||
atomic.StoreInt32(&dirty, 1)
|
||||
if idx := slices.IndexFunc(settings, equal(key)); idx < 0 {
|
||||
settings = append(settings, setting{true, key, val})
|
||||
} else if settings[idx].Value != val {
|
||||
settings[idx].dirty = true
|
||||
settings[idx].Value = val
|
||||
atomic.StoreInt32(&dirty, 1)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -170,7 +177,7 @@ func Float(key string) (float64, error) {
|
|||
func Time(key string) (time.Time, error) {
|
||||
s, err := String(key)
|
||||
if err != nil {
|
||||
return time.Now(), err
|
||||
return time.Time{}, err
|
||||
}
|
||||
return time.Parse(time.RFC3339, s)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue