100 lines
2.1 KiB
Go
100 lines
2.1 KiB
Go
package dualwrite
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"os"
|
|
"sync"
|
|
|
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
|
|
"github.com/grafana/grafana-app-sdk/logging"
|
|
)
|
|
|
|
// Simple file implementation -- useful while testing and not yet sure about the SQL structure!
|
|
// When a path exists, read/write it from disk; otherwise it is held in memory
|
|
type fileDB struct {
|
|
path string
|
|
changed int64
|
|
db map[string]StorageStatus
|
|
mu sync.RWMutex
|
|
logger logging.Logger
|
|
}
|
|
|
|
// File implementation while testing -- values are saved in the data directory
|
|
func newFileDB(path string) *fileDB {
|
|
return &fileDB{
|
|
db: make(map[string]StorageStatus),
|
|
path: path,
|
|
logger: logging.DefaultLogger.With("logger", "fileDB"),
|
|
}
|
|
}
|
|
|
|
func (m *fileDB) Get(ctx context.Context, gr schema.GroupResource) (StorageStatus, bool, error) {
|
|
m.mu.RLock()
|
|
defer m.mu.RUnlock()
|
|
|
|
info, err := os.Stat(m.path)
|
|
if err == nil && info.ModTime().UnixMilli() != m.changed {
|
|
v, err := os.ReadFile(m.path)
|
|
if err == nil {
|
|
err = json.Unmarshal(v, &m.db)
|
|
m.changed = info.ModTime().UnixMilli()
|
|
}
|
|
if err != nil {
|
|
m.logger.Warn("error reading filedb", "err", err)
|
|
}
|
|
|
|
changed := false
|
|
for k, v := range m.db {
|
|
// Must write to unified if we are reading unified
|
|
if v.ReadUnified && !v.WriteUnified {
|
|
v.WriteUnified = true
|
|
m.db[k] = v
|
|
changed = true
|
|
}
|
|
|
|
// Make sure we are writing something!
|
|
if !(v.WriteLegacy || v.WriteUnified) {
|
|
v.WriteLegacy = true
|
|
m.db[k] = v
|
|
changed = true
|
|
}
|
|
}
|
|
if changed {
|
|
err = m.save()
|
|
m.logger.Warn("error saving changes filedb", "err", err)
|
|
}
|
|
}
|
|
|
|
v, ok := m.db[gr.String()]
|
|
return v, ok, nil
|
|
}
|
|
|
|
func (m *fileDB) Set(ctx context.Context, status StorageStatus) error {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
|
|
gr := schema.GroupResource{
|
|
Group: status.Group,
|
|
Resource: status.Resource,
|
|
}
|
|
m.db[gr.String()] = status
|
|
|
|
return m.save()
|
|
}
|
|
|
|
func (m *fileDB) save() error {
|
|
if m.path != "" {
|
|
data, err := json.MarshalIndent(m.db, "", " ")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = os.WriteFile(m.path, data, 0644)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|