RemotePersistenceStore
IPersistenceStore for a worker: every save and load goes to the orchestrator, which owns the real store (PersistenceHost over the dashboard address, the same one the control plane uses).
Nebula · Packages/com.1by3.nebula/Runtime/Persistence/RemotePersistenceStore.cspublic sealed class RemotePersistenceStore : IPersistenceStoreIPersistenceStore for a worker: every save and load goes to the orchestrator, which owns the real store (PersistenceHost over the dashboard address, the same one the control plane uses).
Saves are coalesced per key and posted in batches from a sender thread a fraction of a second after they are issued; a batch the orchestrator cannot take is kept and retried, so nothing is lost while it is away. Reads wait in one queue and MaxConcurrentReads reader threads send them, one request at a time each, retried until they succeed; their answers are handed back from Tick on the main thread like every other store. However many reads are asked for at once, the store never has more than MaxConcurrentReads of them in flight, so a burst of reads cannot swamp the process's thread pool or its connections to the orchestrator, which the control plane's heartbeat shares. LoadContainers asks for up to PersistenceHost.MaxContainersPerLoad containers per request and LoadCarried for up to PersistenceHost.MaxCarriersPerLoad carriers. IsConnected and KnownCount come from a status probe every few seconds.
Constructors
RemotePersistenceStore
public RemotePersistenceStore(string url, string token = null);Fields
FlushIntervalSeconds
public const float FlushIntervalSeconds = 0.25f;Seconds saves are gathered before a batch is posted.
StatusIntervalSeconds
public const float StatusIntervalSeconds = 5f;RetrySeconds
public const float RetrySeconds = 1f;MaxConcurrentReads
public const int MaxConcurrentReads = 2;Reader threads, and so the most read requests this store has in flight at once.
Properties
Url
public string Url { get; }IsConnected
public bool IsConnected { get; }Backend
public string Backend { get; }KnownCount
public int KnownCount { get; }PendingWrites
public int PendingWrites { get; }Saves and deletes waiting for the next batch.
PendingReads
public int PendingReads { get; }Read requests queued or in flight.
Methods
Connect
public void Connect();Tick
public void Tick();Save
public void Save(PersistedEntityRecord record);Delete
public void Delete(string key);Clear
public void Clear();WhenWritten
public void WhenWritten(Action onWritten);Load
public void Load(string key, Action<PersistedEntityRecord> onLoaded);LoadContainers
public void LoadContainers(IReadOnlyList<string> containerIds, Action<IReadOnlyDictionary<string, IReadOnlyList<PersistedEntityRecord>>> onLoaded);POST /api/store/containers, PersistenceHost.MaxContainersPerLoad ids per request; a longer list becomes several requests in the read queue and is still answered once, when all are back.
LoadCarried
public void LoadCarried(IReadOnlyList<string> carrierKeys, Action<IReadOnlyDictionary<string, IReadOnlyList<PersistedEntityRecord>>> onLoaded);POST /api/store/carried, PersistenceHost.MaxCarriersPerLoad keys per request; a longer list becomes several requests in the read queue and is still answered once, when all are back.
LoadWhere
public void LoadWhere(Func<PersistedEntityRecord, bool> predicate, Action<IReadOnlyList<PersistedEntityRecord>> onLoaded);Fetches every record and filters here: the predicate cannot travel. For tools, not the restore path.
CountRecords
public void CountRecords(string scopeKey, string containerId, Action<int> onCounted);Counted on the orchestrator (GET /api/store/count): only the number travels, never the records.
Dispose
public void Dispose();