Fauna Driver and Serverless HTTP Runtime Boundary: Stream Reconnect Reconciliation vs. Temporal Snapshot Deduplication
0 reputation · 16 Sept 2023, 14:04 UTC
0 reputation · 16 Sept 2023, 14:04 UTC
When an application consumes Fauna document streams from a serverless or edge HTTP runtime, the official driver exposes a single stream API while the platform's HTTP agent, proxy, and egress controls sit between the client and Fauna. The integration must choose a reconnect reconciliation policy: whether a resumed stream combined with a temporal snapshot read is treated as at-least-once with idempotent upserts, or as exactly-once by comparing snapshots.
Fauna's query protocol is stateless over HTTPS, so no server-side connection pool is visible to the client; socket reuse, idle timeouts, and retry behavior originate from the runtime or HTTP library. Driver defaults for timeouts, retries, and streaming are version-sensitive and may differ across language drivers and region groups. Fauna supplies stream resumption and temporal history primitives, but it does not define an application-level dedupe or ordering guarantee across reconnects and point-in-time reads.
Which reconciliation model is appropriate when a document appears in both a resumed stream and a temporal snapshot read? How should ordering be determined when the runtime's HTTP layer recycles connections mid-stream? What driver-version or region-group differences must be validated before relying on stream resumption semantics?
33775 reputation · 17 Sept 2023, 01:07 UTC
When a Fauna document appears in both a resumed stream and a temporal snapshot, the safest practical approach is to treat the integration as at‑least‑once with idempotent upserts. Fauna’s protocol guarantees that each event carries a unique ref and a monotonically increasing ts. If your application upserts on ref (or ref+ts) and ignores duplicate ts values, the duplicate will be harmless. Exactly‑once semantics cannot be enforced by Fauna alone; the client must persist the last processed after cursor and compare snapshot timestamps to avoid re‑processing.
Events are ordered by Fauna’s global transaction timestamp (ts). When the HTTP runtime recycles a connection mid‑stream, the driver must preserve the last after cursor. If the cursor is lost, the stream restarts from the beginning (or a configured start_ts), causing re‑delivery of earlier events. Driver implementations differ: JavaScript/TypeScript drivers store the cursor in memory only; Go and Java drivers expose cursor accessors for external persistence.
WithStreamResumeCursor (Go 2.5+, JS 4.7+, Python 5.0+). Older releases retry without cursor preservation.db.eu.fauna.com for EU). Classic region endpoints may have different idle‑timeout defaults.keepAlive or heartbeat intervals are lower than the smallest idle timeout imposed by the serverless runtime (often 10–30 s).Enable debug logging (e.g., FAUNA_DEBUG=1 for the JS driver). Capture the after cursor on each event.
Write a test that starts a stream, injects N documents, kills the socket (via tcpkill or a proxy), and restarts the stream using the persisted cursor.
Assert that exactly N events are received and that each ref+ts pair is unique.
Run a snapshot read at ts = last_processed_ts and confirm no documents newer than that timestamp are returned.
Verify the driver’s maxRetries and retryIntervalMs settings are tuned for the platform’s idle limits.
Before relying on stream resumption semantics, please share:
These details determine whether your driver can persist cursors across reconnects and whether the platform will allow the driver’s heartbeat cadence.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.