Table of Contents

Class ReconnectSupervisor

Namespace
DatabentoDotNet.Extensions.Hosting
Assembly
DatabentoDotNet.Extensions.Hosting.dll

The reconnection schedule for one live session: exponential backoff with jitter, bounded by consecutive failures.

public sealed class ReconnectSupervisor
Inheritance
ReconnectSupervisor
Inherited Members

Remarks

Why this exists at all, given PORTING.md §4. That file says twice that reconnect and resubscribe are deliberately separate and are not to be fused into an auto-reconnect. That is a rule about LiveClient, and a hosted service is precisely the caller it defers to: the library still does not fuse them, and this type makes the caller's decision once, explicitly, with a bound on it.

MaxAttempts bounds consecutive failures and RecordSuccess() resets the counter, so a gateway that flaps every ten minutes reconnects indefinitely. That is deliberate — the alternative silently stops a worker overnight. Every successful reconnect starts a newly billed session, so a reconnect storm is a billing event and not merely a connection event; the bound is what caps it.

Equal jitter, and it is not configurable. Each delay is uniform between half the base and the base. Full jitter — uniform between zero and the base — turns a bounded backoff into a tight retry loop against a gateway that is already struggling, and each attempt costs money. The purpose of any jitter here is to stop a restarted fleet reconnecting in lockstep, and a knob for that is a knob whose correct value is never anything but "on".

Constructors

ReconnectSupervisor(ResolvedReconnect)

Creates a supervisor for one policy.

public ReconnectSupervisor(ResolvedReconnect policy)

Parameters

policy ResolvedReconnect

Properties

ConsecutiveFailures

How many attempts have been handed out since the last RecordSuccess().

public int ConsecutiveFailures { get; }

Property Value

int

Delay

Waits out a delay. Defaults to a real wait.

public Func<Duration, CancellationToken, Task> Delay { get; init; }

Property Value

Func<Duration, CancellationToken, Task>

Remarks

The same kind of seam as Jitter, and it is what lets LiveSessionReconnectTests assert a thirty-second backoff without taking thirty seconds. Duration.ToTimeSpan() rather than the banned type by name.

Jitter

Supplies the jitter factor, in [0, 1). Defaults to Shared.

public Func<double> Jitter { get; init; }

Property Value

Func<double>

Remarks

A seam so a test can state the schedule, not a knob: nothing in the options model reaches this, and nothing should.

The [0, 1) above is enforced, not merely requested. TryNextDelay(out Duration) clamps whatever this returns, because both properties the schedule actually promises depend on it: a factor above 1 would put a delay past the MaxDelay ceiling BaseDelay(int) just capped it at, and one below 0 would put it under the half-the-base floor that is the whole difference between equal jitter and full jitter. This is a public init property, so "a caller would not do that" is an assumption about a caller rather than a property of this type.

Policy

The policy this supervisor enforces.

public ResolvedReconnect Policy { get; }

Property Value

ResolvedReconnect

Methods

RecordSuccess()

Records that a session started, resetting the consecutive-failure count.

public void RecordSuccess()

TryNextDelay(out Duration)

Takes the next delay, or reports that the policy is exhausted or disabled.

public bool TryNextDelay(out Duration delay)

Parameters

delay Duration

The delay to wait before the next attempt, or zero on false.

Returns

bool

true when another attempt is allowed.