feat: add BVK exchange library
This commit is contained in:
84
store_file.go
Normal file
84
store_file.go
Normal file
@@ -0,0 +1,84 @@
|
||||
package mila
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type FileStore struct {
|
||||
path string
|
||||
mu sync.Mutex
|
||||
mem *MemoryStore
|
||||
}
|
||||
|
||||
func NewFileStore(path string) *FileStore {
|
||||
return &FileStore{
|
||||
path: path,
|
||||
mem: NewMemoryStore(),
|
||||
}
|
||||
}
|
||||
|
||||
func (s *FileStore) Get(ctx context.Context) (ContentState, error) {
|
||||
if state, err := s.mem.Get(ctx); err == nil {
|
||||
return state, nil
|
||||
}
|
||||
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
data, err := os.ReadFile(s.path)
|
||||
if err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return ContentState{}, ErrNotReady
|
||||
}
|
||||
return ContentState{}, err
|
||||
}
|
||||
|
||||
var state ContentState
|
||||
if err := json.Unmarshal(data, &state); err != nil {
|
||||
return ContentState{}, err
|
||||
}
|
||||
if state.IsZero() {
|
||||
return ContentState{}, ErrNotReady
|
||||
}
|
||||
|
||||
if err := s.mem.Set(ctx, state); err != nil {
|
||||
return ContentState{}, err
|
||||
}
|
||||
return state, nil
|
||||
}
|
||||
|
||||
func (s *FileStore) Set(ctx context.Context, state ContentState) error {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
if err := os.MkdirAll(filepath.Dir(s.path), 0o755); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
data, err := json.MarshalIndent(state, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tmp := s.path + ".tmp"
|
||||
if err := os.WriteFile(tmp, data, 0o644); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.Rename(tmp, s.path); err != nil {
|
||||
_ = os.Remove(tmp)
|
||||
return err
|
||||
}
|
||||
|
||||
return s.mem.Set(ctx, state)
|
||||
}
|
||||
Reference in New Issue
Block a user