You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tailscale/ipn/store/mem/store_mem.go

71 lines
1.5 KiB
Go

// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
// Package mem provides an in-memory ipn.StateStore implementation.
package mem
import (
"bytes"
"encoding/json"
"sync"
"tailscale.com/ipn"
"tailscale.com/types/logger"
)
// New returns a new Store.
func New(logger.Logf, string) (ipn.StateStore, error) {
return new(Store), nil
}
// Store is an ipn.StateStore that keeps state in memory only.
type Store struct {
mu sync.Mutex
// +checklocks:mu
cache map[ipn.StateKey][]byte
}
func (s *Store) String() string { return "mem.Store" }
// ReadState implements the StateStore interface.
func (s *Store) ReadState(id ipn.StateKey) ([]byte, error) {
s.mu.Lock()
defer s.mu.Unlock()
bs, ok := s.cache[id]
if !ok {
return nil, ipn.ErrStateNotExist
}
return bs, nil
}
// WriteState implements the StateStore interface.
func (s *Store) WriteState(id ipn.StateKey, bs []byte) error {
s.mu.Lock()
defer s.mu.Unlock()
if s.cache == nil {
s.cache = map[ipn.StateKey][]byte{}
}
s.cache[id] = bytes.Clone(bs)
return nil
}
// LoadFromJSON attempts to unmarshal json content into the
// in-memory cache.
func (s *Store) LoadFromJSON(data []byte) error {
s.mu.Lock()
defer s.mu.Unlock()
return json.Unmarshal(data, &s.cache)
}
// ExportToJSON exports the content of the cache to
// JSON formatted []byte.
func (s *Store) ExportToJSON() ([]byte, error) {
s.mu.Lock()
defer s.mu.Unlock()
if len(s.cache) == 0 {
// Avoid "null" serialization.
return []byte("{}"), nil
}
return json.MarshalIndent(s.cache, "", " ")
}