Skip to content

Commit

Permalink
Merge pull request #316 from SiaFoundation/chris/cache-settings
Browse files Browse the repository at this point in the history
Cache settings in memory
  • Loading branch information
ChrisSchinnerl authored Apr 28, 2023
2 parents 021f623 + e8dc253 commit 53b1d27
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 2 deletions.
30 changes: 28 additions & 2 deletions stores/settingsdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,26 @@ func (dbSetting) TableName() string { return "settings" }

// DeleteSetting implements the bus.SettingStore interface.
func (s *SQLStore) DeleteSetting(ctx context.Context, key string) error {
// Delete from cache.
s.settingsMu.Lock()
delete(s.settings, key)
s.settingsMu.Unlock()

// Delete from database.
return s.db.Where(&dbSetting{Key: key}).Delete(&dbSetting{}).Error
}

// Setting implements the bus.SettingStore interface.
func (s *SQLStore) Setting(ctx context.Context, key string) (string, error) {
// Check cache first.
s.settingsMu.Lock()
defer s.settingsMu.Unlock()
value, ok := s.settings[key]
if ok {
return value, nil
}

// Check database.
var entry dbSetting
err := s.db.Where(&dbSetting{Key: key}).
Take(&entry).Error
Expand All @@ -37,7 +52,7 @@ func (s *SQLStore) Setting(ctx context.Context, key string) (string, error) {
} else if err != nil {
return "", err
}

s.settings[key] = entry.Value
return entry.Value, nil
}

Expand All @@ -50,11 +65,22 @@ func (s *SQLStore) Settings(ctx context.Context) ([]string, error) {

// UpdateSetting implements the bus.SettingStore interface.
func (s *SQLStore) UpdateSetting(ctx context.Context, key, value string) error {
return s.db.Clauses(clause.OnConflict{
// Update db first.
s.settingsMu.Lock()
defer s.settingsMu.Unlock()

err := s.db.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "key"}},
DoUpdates: clause.AssignmentColumns([]string{"value"}),
}).Create(&dbSetting{
Key: key,
Value: value,
}).Error
if err != nil {
return err
}

// Update cache second.
s.settings[key] = value
return nil
}
14 changes: 14 additions & 0 deletions stores/settingsdb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ package stores

import (
"context"
"errors"
"testing"

"go.sia.tech/renterd/api"
)

// TestSQLSettingStore tests the bus.SettingStore methods on the SQLSettingStore.
Expand Down Expand Up @@ -49,4 +52,15 @@ func TestSQLSettingStore(t *testing.T) {
} else if value != "barbaz" {
t.Fatalf("unexpected value, %s != 'barbaz'", value)
}

// delete the setting
if err := ss.DeleteSetting(ctx, "foo"); err != nil {
t.Fatal(err)
} else if _, err := ss.Setting(ctx, "foo"); !errors.Is(err, api.ErrSettingNotFound) {
t.Fatal("should fail with gorm.ErrRecordNotFound", err)
} else if keys, err := ss.Settings(ctx); err != nil {
t.Fatal(err)
} else if len(keys) != 0 {
t.Fatalf("unexpected number of settings, %v != 0", len(keys))
}
}
5 changes: 5 additions & 0 deletions stores/sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ type (
unappliedRevisions map[types.FileContractID]revisionUpdate
unappliedProofs map[types.FileContractID]uint64

// SettingsDB related fields.
settingsMu sync.Mutex
settings map[string]string

mu sync.Mutex
hasAllowlist bool
hasBlocklist bool
Expand Down Expand Up @@ -207,6 +211,7 @@ func NewSQLStore(conn gorm.Dialector, migrate bool, persistInterval time.Duratio
persistInterval: persistInterval,
hasAllowlist: allowlistCnt > 0,
hasBlocklist: blocklistCnt > 0,
settings: make(map[string]string),
unappliedHostKeys: make(map[types.PublicKey]struct{}),
unappliedRevisions: make(map[types.FileContractID]revisionUpdate),
unappliedProofs: make(map[types.FileContractID]uint64),
Expand Down

0 comments on commit 53b1d27

Please sign in to comment.