Nebula
Interest

InterestSchedule

Which clients a gateway re-evaluates on this tick.

generated from the sources
public sealed class InterestSchedule

Which clients a gateway re-evaluates on this tick. Every client is evaluated at InterestSettings.EvalHz, but never all of them on the same tick: routine evaluations are spread over the ticks of one interval by a cursor walking a ring, at a budget derived from the time the tick actually took. A hundred clients on a 60 Hz loop at 4 Hz evaluation cost about seven evaluations a tick instead of a hundred every fifteenth tick, which is the difference between a flat frame time and a loop that stalls four times a second.

Clients marked dirty — a new pawn, a changed instance, a focus-mode change, a policy that says so — are not routine and jump the queue: they are collected before the routine slice, on the next tick. That is bounded too (MinDirtyPerTick, DirtyBurst) so a change that dirties every client at once is spread rather than turned into the stall this class exists to prevent, and the dirty scan has a cursor of its own so a storm cannot keep serving the same few clients.

Steady state allocates nothing: the ring, the slot map and the duplicate guard are reused.

Fields

MinDirtyPerTick

public const int MinDirtyPerTick = 8;

However small the routine budget is, this many dirty clients are always taken in a tick.

DirtyBurst

public const int DirtyBurst = 4;

A tick may take this many times the routine budget in dirty clients before the rest wait.

Properties

Count

public int Count { get; }

Clients in the rotation.

LastDirty

public int LastDirty { get; }

Dirty clients the last Collect took.

LastRoutine

public int LastRoutine { get; }

Routine clients the last Collect took (an already-dirty one does not count twice).

Methods

Add

public bool Add(ulong clientId);

Put a client in the rotation. Idempotent: welcoming a reclaimed session twice is not two clients.

Remove

public bool Remove(ulong clientId);

Take a client out of the rotation. The last entry fills the hole, so removal is O(1).

Contains

public bool Contains(ulong clientId);

Clear

public void Clear();

Collect

public void Collect(double dt, float evalHz, Func<ulong, bool> isDirty, List<ulong> due);

Fill due with the clients to evaluate on this tick: the dirty ones first, then the routine slice, with no id twice. dt is the seconds since the last call, which is what makes the rate independent of the loop's tick rate and honest when a tick runs long.

On this page