pycsamt.iot.protocols.store_forward#

Store-and-forward buffering for intermittent field links.

Remote AMT/CSAMT nodes routinely lose their uplink – a gateway drops out, a cellular backhaul flaps, a boat moves out of range. A bare telemetry client raises TelemetryError on every send in that window and the packets are lost. StoreAndForwardClient wraps any BaseTelemetryClient and, when a send fails, queues the packet instead of dropping it. flush() later drains the queue in order, and an optional JSON-lines spool file lets a node survive a restart with its backlog intact.

The semantics are at-least-once and order-preserving: once anything is queued, later packets also queue (so nothing overtakes the backlog), and flush() stops at the first failure, leaving the rest for the next attempt.

Classes

StoreAndForwardClient(client, *[, ...])

Wrap a telemetry client with a persistent offline send buffer.

class pycsamt.iot.protocols.store_forward.StoreAndForwardClient(client, *, spool_path=None, max_queue=None, base_backoff_s=1.0, max_backoff_s=300.0)[source]#

Bases: object

Wrap a telemetry client with a persistent offline send buffer.

Parameters:
  • client (BaseTelemetryClient) – The underlying transport used for real sends.

  • spool_path (str, optional) – Path to a JSON-lines spool file. When given, the queue is persisted on every change and reloaded on construction, so a node keeps its backlog across restarts.

  • max_queue (int, optional) – Maximum number of buffered packets. When the buffer is full the oldest packet is dropped (the newest data is the most valuable for a live survey). None means unbounded.

  • base_backoff_s (float) – Base delay for the exponential backoff hint (see next_retry_delay_s).

  • max_backoff_s (float) – Ceiling for the backoff hint.

property pending: int[source]#

Number of packets currently buffered.

property next_retry_delay_s: float[source]#

Exponential-backoff hint for when to next call flush().

Returns 0.0 when the queue is empty. After consecutive flush failures the delay grows as base * 2**(failures-1), capped at max_backoff_s – a caller’s scheduling loop can honour this without this class ever sleeping itself.

send(packet)[source]#

Send packet, or queue it when the transport is unavailable.

A direct send is attempted only when the buffer is empty, so a backlog is never overtaken by fresh packets. On transport failure the packet is queued and a queued acknowledgement is returned rather than raising.

Parameters:

packet (Any)

Return type:

TelemetryAck

flush()[source]#

Drain the buffer in order; return the number of packets sent.

Sending stops at the first failure, leaving the remaining packets queued for a later attempt (at-least-once, order-preserving).

Return type:

int