Treat link drops as routine: Orin detects, redelivers or expires

PD changes through the tablet's hub reset the USB link for 5-12 s at
every ignition change. The app still re-dials, but the Orin must notice
dead clients by heartbeat (TCP alone leaves half-open sockets), keep
pending reliable traffic to redeliver or expire by age, and accept
idempotent commands so retries across reconnects never act twice.
Recorded as proposed decision 24; no implementation yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mikkeli
2026-10-09 00:18:50 +09:00
parent ac4626640c
commit 5bff21265b
+22 -1
View File
@@ -143,7 +143,27 @@ pressure, upstream plain request/response.** That is decision 9 generalised from
route requests to everything the app sends. route requests to everything the app sends.
The app always initiates. The Orin listens and never dials out to a display, so The app always initiates. The Orin listens and never dials out to a display, so
reconnection is entirely the client's problem. re-dialling is the client's job. Noticing the loss and redelivering is the Orin's.
### Link drops are routine, not exceptional
Measured on the USB path (tablet ↔ PD hub ↔ Orin, 2026-10-09): every PD power
change resets the hub's data port. The link flaps about three times and is back
within 5–12 s, with no intervention. In the car this happens at every ignition
change. Design for it as normal operation. Requirements, not yet implemented:
- **Failure detection on the Orin.** An app-level heartbeat with a timeout of a
few seconds, not TCP alone. A connection on a link that went down can stay
half-open long after the app has re-dialled. Reap dead connections and their
per-client queues promptly.
- **Downstream (latest-wins):** unchanged. On reconnect, push current state; no
resend, since stale samples are worthless.
- **Reliable channel (TTS chunks, acknowledgements):** pending items survive a
drop. Redeliver on reconnect, or expire by age (an utterance that is several
seconds late is better dropped than played). Within the window, a reconnect
should resume rather than start over.
- **Upstream retries cross reconnects**, so commands carry an idempotency key.
At-least-once delivery then never means acting twice.
### Cloud links are outbound-initiated ### Cloud links are outbound-initiated
@@ -327,6 +347,7 @@ rewriting the document.
| 21 | Two clocks per envelope; `monotonic` orders, `timestamp` references | Accepted | 2026-09-05 | | 21 | Two clocks per envelope; `monotonic` orders, `timestamp` references | Accepted | 2026-09-05 |
| 22 | `signals.json` is the single source for signal name and unit; both are derived, never authored twice | Accepted | 2026-09-05 | | 22 | `signals.json` is the single source for signal name and unit; both are derived, never authored twice | Accepted | 2026-09-05 |
| 23 | Services build natively on the development Orin; both units stay on the same L4T release | Accepted | 2026-09-05 | | 23 | Services build natively on the development Orin; both units stay on the same L4T release | Accepted | 2026-09-05 |
| 24 | Link drops are routine: `svc-gw` detects dead clients by heartbeat and redelivers or expires pending reliable traffic; upstream commands are idempotent | **Proposed** | 2026-10-09 |
| 6 | Local logging first; off-board LTE telemetry deferred | Accepted | 2026-08-14 | | 6 | Local logging first; off-board LTE telemetry deferred | Accepted | 2026-08-14 |
| 7 | Camera/AI inference is a later, separate task | Accepted | 2026-08-14 | | 7 | Camera/AI inference is a later, separate task | Accepted | 2026-08-14 |
| 8 | Self-hosted offline navigation (MapLibre GL + Valhalla + PMTiles) over a cloud maps SDK | Accepted | 2026-09-03 | | 8 | Self-hosted offline navigation (MapLibre GL + Valhalla + PMTiles) over a cloud maps SDK | Accepted | 2026-09-03 |