mirror of
https://github.com/kopia/kopia.git
synced 2026-03-17 21:56:14 -04:00
Add metadata R/W locking for asynchronous accesses to robustness engine metadata. Remove the index from the Store interface and maintain it only in Checker, where it's used.
105 lines
2.4 KiB
Go
105 lines
2.4 KiB
Go
// +build darwin,amd64 linux,amd64
|
|
|
|
package engine
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
|
|
"github.com/kopia/kopia/internal/clock"
|
|
"github.com/kopia/kopia/tests/robustness"
|
|
)
|
|
|
|
const (
|
|
engineStatsStoreKey = "cumulative-engine-stats"
|
|
engineLogsStoreKey = "engine-logs"
|
|
snapIDIndexStoreKey = "checker-snapID-index"
|
|
)
|
|
|
|
// saveLog saves the engine Log in the metadata store.
|
|
func (e *Engine) saveLog() error {
|
|
b, err := json.Marshal(e.EngineLog)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return e.MetaStore.Store(engineLogsStoreKey, b)
|
|
}
|
|
|
|
// loadLog loads the engine log from the metadata store.
|
|
func (e *Engine) loadLog() error {
|
|
b, err := e.MetaStore.Load(engineLogsStoreKey)
|
|
if err != nil {
|
|
if errors.Is(err, robustness.ErrKeyNotFound) {
|
|
// Swallow key-not-found error. May not have historical logs
|
|
return nil
|
|
}
|
|
|
|
return err
|
|
}
|
|
|
|
err = json.Unmarshal(b, &e.EngineLog)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
e.EngineLog.runOffset = len(e.EngineLog.Log)
|
|
|
|
return err
|
|
}
|
|
|
|
// saveStats saves the engine Stats in the metadata store.
|
|
func (e *Engine) saveStats() error {
|
|
cumulStatRaw, err := json.Marshal(e.CumulativeStats)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return e.MetaStore.Store(engineStatsStoreKey, cumulStatRaw)
|
|
}
|
|
|
|
// loadStats loads the engine Stats from the metadata store.
|
|
func (e *Engine) loadStats() error {
|
|
b, err := e.MetaStore.Load(engineStatsStoreKey)
|
|
if err != nil {
|
|
if errors.Is(err, robustness.ErrKeyNotFound) {
|
|
// Swallow key-not-found error. We may not have historical
|
|
// stats data. Initialize the action map for the cumulative stats
|
|
e.CumulativeStats.PerActionStats = make(map[ActionKey]*ActionStats)
|
|
e.CumulativeStats.CreationTime = clock.Now()
|
|
|
|
return nil
|
|
}
|
|
|
|
return err
|
|
}
|
|
|
|
return json.Unmarshal(b, &e.CumulativeStats)
|
|
}
|
|
|
|
// saveSnapIDIndex saves the Checker's snapshot ID index in the metadata store.
|
|
func (e *Engine) saveSnapIDIndex() error {
|
|
snapIDIdxRaw, err := json.Marshal(e.Checker.SnapIDIndex)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return e.MetaStore.Store(snapIDIndexStoreKey, snapIDIdxRaw)
|
|
}
|
|
|
|
// loadSnapIDIndex loads the Checker's snapshot ID index from the metadata store.
|
|
func (e *Engine) loadSnapIDIndex() error {
|
|
b, err := e.MetaStore.Load(snapIDIndexStoreKey)
|
|
if err != nil {
|
|
if errors.Is(err, robustness.ErrKeyNotFound) {
|
|
// Swallow key-not-found error. We may not have historical
|
|
// index data.
|
|
return nil
|
|
}
|
|
|
|
return err
|
|
}
|
|
|
|
return json.Unmarshal(b, &e.Checker.SnapIDIndex)
|
|
}
|