mirror of
https://github.com/netbirdio/netbird.git
synced 2026-07-16 03:29:57 +00:00
* Persist sync response via pluggable store (disk on iOS)
The latest Management sync response (which carries the network map) was
kept in memory for debug bundle generation. On memory-constrained
platforms like iOS the network map can be large enough to matter.
Introduce a syncstore package with a Store interface and two backends:
a memory backend (the previous behavior) and a disk backend that
serializes the response to a file in the state directory. The backend
is selected per-platform at build time: disk on iOS, memory elsewhere.
The disk store clears any leftover file on construction so a fresh
store never reads stale data from an earlier run (e.g. another
profile's network map).
In the engine, drop the separate persistSyncResponse bool: the store is
only instantiated while persistence is enabled, and its presence is
what marks persistence as active. The store is also cleared on engine
close so the file does not linger on disk.
* syncstore: silence nilnil linter on "nothing stored" returns
Get returns (nil, nil) to signal that nothing is stored, which is part
of the Store contract and preserves the original behaviour. Annotate
both backends with //nolint:nilnil so golangci-lint does not flag it.
* syncstore: hold syncRespMux for the whole store Set/Get
Both handleSync and GetLatestSyncResponse snapshotted e.syncStore under
the read lock and then released it before calling Set/Get. That allowed
SetSyncResponsePersistence(false) or engine close to clear the store
mid-call. In particular a concurrent Clear()+nil followed by a late
Set could re-create the file that was just removed, defeating the
leak/lingering protection.
Hold syncRespMux for the duration of the store operation in both spots
so the store cannot be cleared while a Set/Get is in flight.
* syncstore: avoid StateDir "." when state path is empty
On mobile the state path may be empty (the engine tolerates a missing
state file). filepath.Dir("") returns ".", which would make a
disk-backed syncstore write into the working directory instead of
letting NewDiskStore fall back to os.TempDir().
Only set engineConfig.StateDir when path is non-empty.
30 lines
1.1 KiB
Go
30 lines
1.1 KiB
Go
// Package syncstore stores the latest Management sync response (which carries
|
|
// the network map) for debug bundle generation.
|
|
//
|
|
// The storage backend is selected at build time per operating system: on iOS
|
|
// the response is serialized to disk to keep it out of the (tightly
|
|
// constrained) process memory, while on all other platforms it is kept in
|
|
// memory. The backend is chosen by the New constructor; see factory_ios.go and
|
|
// factory_other.go.
|
|
package syncstore
|
|
|
|
import (
|
|
mgmProto "github.com/netbirdio/netbird/shared/management/proto"
|
|
)
|
|
|
|
// Store persists the latest sync response and returns it on demand.
|
|
//
|
|
// Implementations must be safe for concurrent use.
|
|
type Store interface {
|
|
// Set stores the given sync response, replacing any previously stored one.
|
|
Set(resp *mgmProto.SyncResponse) error
|
|
|
|
// Get returns the stored sync response, or nil if none is stored.
|
|
// The returned value is an independent copy that the caller may retain.
|
|
Get() (*mgmProto.SyncResponse, error)
|
|
|
|
// Clear removes any stored sync response. It is safe to call when nothing
|
|
// is stored.
|
|
Clear() error
|
|
}
|