Nebula
Control plane

ControlPlaneHost

The control plane as the orchestrator hosts it: a LocalControlPlane that is the source of truth, served to workers and gateways over the orchestrator's HTTP server and kept in an IControlPlaneStorage between runs.

generated from the sources
public sealed partial class ControlPlaneHost : IControlPlane

The control plane as the orchestrator hosts it: a LocalControlPlane that is the source of truth, served to workers and gateways over the orchestrator's HTTP server and kept in an IControlPlaneStorage between runs.

  • GET /api/control-plane?since=<version>&wait=<seconds> answers with the current document (ControlPlaneJson) as soon as its version is above since, or when wait seconds pass. Subscribers (RemoteControlPlane) keep one such request open.
  • POST /api/control-plane with {"ops":[...]} applies writes in order on the main thread (through TryHandle, from the orchestrator's command pump), so the orchestrator sees them in the same tick it would see its own.

With a mesh token every request carries it in the X-Nebula-Token header; without one the API is open, which is fine on a private network or a development machine. Reads are answered on the listener thread from the last published document, so the orchestrator's main thread never waits on a subscriber.

Constructors

ControlPlaneHost

public ControlPlaneHost(IControlPlaneStorage storage, string token, bool restore = true);
ParameterDescription
storageWhere the document is kept between runs; null keeps it in memory only.
tokenShared secret subscribers must present; null or empty for none.
restoreRead the stored document at Connect. The orchestrator resets the plane when it initializes unless -nebula-reset false, so this only matters then.

Fields

Path

public const string Path = "/api/control-plane";

TokenHeader

public const string TokenHeader = "X-Nebula-Token";

MaxWaitSeconds

public const int MaxWaitSeconds = 30;

Longest a subscriber may ask a read to wait for a change.

SaveIntervalSeconds

public float SaveIntervalSeconds = 1f;

Seconds between writes to storage while the control plane keeps changing.

Properties

Plane

public LocalControlPlane Plane { get; }

The state machine itself, for tests.

StorageBackend

public string StorageBackend { get; }

StorageError

public string StorageError { get; }

Error from the latest background save, or null before a save fails or after a successful save. Failed saves are retried at the next save interval while the control plane continues using its in-memory state.

HasToken

public bool HasToken { get; }

PublishedVersion

public long PublishedVersion { get; }

Version of the document subscribers currently receive.

IsConnected

public bool IsConnected { get; }

Now

public DateTime Now { get; }

DocumentId

public string DocumentId { get; }

Identity of the hosted control-plane document; see IControlPlane.DocumentId.

Workers

public IReadOnlyList<WorkerInfo> Workers { get; }

Leases

public IReadOnlyList<LeaseInfo> Leases { get; }

Gateways

public IReadOnlyList<GatewayInfo> Gateways { get; }

Settings

public IReadOnlyDictionary<string, string> Settings { get; }

Scopes

public IReadOnlyList<ScopeInfo> Scopes { get; }

Events

Changed

public event Action Changed;

Methods

Connect

public void Connect();

Tick

public void Tick();

Dispose

public void Dispose();

RegisterWorker

public void RegisterWorker(string workerId, uint workerIndex, string address, ushort port);

HeartbeatWorker

public void HeartbeatWorker(string workerId, string status, in WorkerStats stats);

UnregisterWorker

public void UnregisterWorker(string workerId);

RegisterGateway

public void RegisterGateway(string gatewayId, string address, ushort port, uint incarnation = 0);

HeartbeatGateway

public void HeartbeatGateway(string gatewayId, in GatewayStats stats);

UnregisterGateway

public void UnregisterGateway(string gatewayId);

SetGatewayDraining

public void SetGatewayDraining(string gatewayId, bool draining);

HeartbeatOrchestrator

public void HeartbeatOrchestrator(string orchestratorId, uint desiredWorkers);

SetSetting

public void SetSetting(string key, string value);

EnsureContainer

public void EnsureContainer(string containerId, ContainerAuthority authority = ContainerAuthority.Auto, bool ownPhysicsFrame = false, FrameInterestMode frameInterest = FrameInterestMode.WithCarrier, float frameApproachMargin = 0f);

EnsureRuntimeContainer

public void EnsureRuntimeContainer(string containerId, ContainerPlacement placement, string workerId, InstanceContainerInfo instance = null);

TouchContainer

public void TouchContainer(string containerId);

AssignContainer

public void AssignContainer(string containerId, string workerId);

PinContainer

public void PinContainer(string containerId, string workerId);

SetLeaseState

public void SetLeaseState(string containerId, string state);

SetContainerHint

public void SetContainerHint(string containerId, in ContainerHint hint);

SetContainerCapacity

public void SetContainerCapacity(string containerId, float saturation, CostComponent dominant, bool atCapacity, SaturationCause cause = SaturationCause.None);

ReleaseContainer

public void ReleaseContainer(string containerId);

RemoveContainer

public void RemoveContainer(string containerId);

ResetControlPlane

public void ResetControlPlane();

Attach

public void Attach(OrchestratorHttpServer http);

Serve reads from http. Writes go through TryHandle from the command pump.

TryHandle

public bool TryHandle(OrchestratorHttpServer.Request req, out OrchestratorHttpServer.Response response);

Main thread: apply a batch of writes when req is one. Returns false for any other request so the caller can handle it.

ActivateScope

public void ActivateScope(ScopeActivationRequest request);

SetScopeState

public void SetScopeState(string scopeKey, string state);

AckScopePart

public void AckScopePart(string scopeKey, string containerId, string phase, int count, string workerId);

RemoveScope

public void RemoveScope(string scopeKey);

On this page