Nebula
Persistence

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).

generated from the sources
public sealed class RemotePersistenceStore : IPersistenceStore

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).

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();

On this page