Nebula
Storage

SqlPersistenceStore

IPersistenceStore in the orchestrator's database (NebulaDatabase: SQLite or PostgreSQL), table nebula_entity.

generated from the sources
public sealed class SqlPersistenceStore : IPersistenceStore

IPersistenceStore in the orchestrator's database (NebulaDatabase: SQLite or PostgreSQL), table nebula_entity. One writer thread runs every save, delete and query in order on one connection, so the epoch rule (a save older than what is stored is dropped) is one conditional upsert and a later save never overtakes an earlier one. Answers are handed back from Tick on the main thread. When the database is unreachable the queue waits and the connection is retried; the mesh keeps simulating meanwhile, and workers keep their own queues (RemotePersistenceStore).

Constructors

SqlPersistenceStore

public SqlPersistenceStore(NebulaDatabase db);

Fields

RetrySeconds

public const float RetrySeconds = 2f;

CountIntervalSeconds

public const float CountIntervalSeconds = 2f;

Seconds between refreshes of KnownCount while writes keep coming.

Properties

IsConnected

public bool IsConnected { get; }

Backend

public string Backend { get; }

KnownCount

public int KnownCount { get; }

PendingJobs

public int PendingJobs { get; }

Jobs waiting for the writer thread.

StaleSavesDropped

public long StaleSavesDropped { get; }

Saves refused since the store was created because the stored record had a newer epoch. The first refusal of each key is also logged as a warning.

Methods

Connect

public void Connect();

Tick

public void Tick();

Dispose

public void Dispose();

Save

public void Save(PersistedEntityRecord record);

Delete

public void Delete(string key);

WhenWritten

public void WhenWritten(Action onWritten);

Clear

public void Clear();

Load

public void Load(string key, Action<PersistedEntityRecord> onLoaded);

LoadContainers

public void LoadContainers(IReadOnlyList<string> containerIds, Action<IReadOnlyDictionary<string, IReadOnlyList<PersistedEntityRecord>>> onLoaded);

One job on the writer thread, one SELECT ... WHERE container_id IN (...) per PersistenceHost.MaxContainersPerLoad ids (the nebula_entity_container index answers it), answered once when every chunk has been read.

LoadCarried

public void LoadCarried(IReadOnlyList<string> carrierKeys, Action<IReadOnlyDictionary<string, IReadOnlyList<PersistedEntityRecord>>> onLoaded);

One job on the writer thread, one SELECT ... WHERE carrier_key IN (...) per PersistenceHost.MaxCarriersPerLoad keys (the nebula_entity_carrier index answers it), answered once when every chunk has been read.

LoadWhere

public void LoadWhere(Func<PersistedEntityRecord, bool> predicate, Action<IReadOnlyList<PersistedEntityRecord>> onLoaded);

CountRecords

public void CountRecords(string scopeKey, string containerId, Action<int> onCounted);

A COUNT on the scope key (and the container id when one is given): no row is read back.

On this page