mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-29 04:55:31 +00:00
853fe3b713
Some checks are pending
checklocks / checklocks (push) Waiting to run
CodeQL / Analyze (go) (push) Waiting to run
Dockerfile build / deploy (push) Waiting to run
CI / test (-coverprofile=/tmp/coverage.out, amd64) (push) Waiting to run
CI / race-root-integration (1/4) (push) Waiting to run
CI / race-root-integration (2/4) (push) Waiting to run
CI / race-root-integration (3/4) (push) Waiting to run
CI / race-root-integration (4/4) (push) Waiting to run
CI / test (-race, amd64, 1/3) (push) Waiting to run
CI / test (-race, amd64, 2/3) (push) Waiting to run
CI / test (-race, amd64, 3/3) (push) Waiting to run
CI / test (386) (push) Waiting to run
CI / windows (push) Waiting to run
CI / privileged (push) Waiting to run
CI / vm (push) Waiting to run
CI / race-build (push) Waiting to run
CI / cross (386, linux) (push) Waiting to run
CI / cross (arm, 5, linux) (push) Waiting to run
CI / cross (amd64, darwin) (push) Waiting to run
CI / cross (amd64, freebsd) (push) Waiting to run
CI / cross (amd64, openbsd) (push) Waiting to run
CI / cross (amd64, windows) (push) Waiting to run
CI / cross (arm, 7, linux) (push) Waiting to run
CI / cross (loong64, linux) (push) Waiting to run
CI / ios (push) Waiting to run
CI / crossmin (amd64, plan9) (push) Waiting to run
CI / crossmin (ppc64, aix) (push) Waiting to run
CI / android (push) Waiting to run
CI / wasm (push) Waiting to run
CI / tailscale_go (push) Waiting to run
CI / fuzz (push) Waiting to run
CI / depaware (push) Waiting to run
CI / go_generate (push) Waiting to run
CI / go_mod_tidy (push) Waiting to run
CI / licenses (push) Waiting to run
CI / staticcheck (386, windows) (push) Waiting to run
CI / staticcheck (amd64, darwin) (push) Waiting to run
CI / staticcheck (amd64, linux) (push) Waiting to run
CI / staticcheck (amd64, windows) (push) Waiting to run
CI / cross (arm64, darwin) (push) Waiting to run
CI / cross (arm64, linux) (push) Waiting to run
CI / cross (arm64, windows) (push) Waiting to run
CI / notify_slack (push) Blocked by required conditions
CI / check_mergeability (push) Blocked by required conditions
Cache state in memory on writes, read from memory in reads. kubestore was previously always reading state from a Secret. This change should fix bugs caused by temporary loss of access to kube API server and imporove overall performance Fixes #7671 Updates tailscale/tailscale#12079,tailscale/tailscale#13900 Signed-off-by: Maisem Ali <maisem@tailscale.com> Signed-off-by: Irbe Krumina <irbe@tailscale.com> Co-authored-by: Maisem Ali <maisem@tailscale.com>
88 lines
2.0 KiB
Go
88 lines
2.0 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"
|
|
|
|
xmaps "golang.org/x/exp/maps"
|
|
"tailscale.com/ipn"
|
|
"tailscale.com/types/logger"
|
|
"tailscale.com/util/mak"
|
|
)
|
|
|
|
// 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.
|
|
// It returns ipn.ErrStateNotExist if the state does not exist.
|
|
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.
|
|
// It never returns an error.
|
|
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
|
|
}
|
|
|
|
// LoadFromMap loads the in-memory cache from the provided map.
|
|
// Any existing content is cleared, and the provided map is
|
|
// copied into the cache.
|
|
func (s *Store) LoadFromMap(m map[string][]byte) {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
xmaps.Clear(s.cache)
|
|
for k, v := range m {
|
|
mak.Set(&s.cache, ipn.StateKey(k), v)
|
|
}
|
|
return
|
|
}
|
|
|
|
// 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, "", " ")
|
|
}
|