3 Commits

Author SHA1 Message Date
f22fb29964 python + typescript + bash: mirror the durability fixes from go/
Parity pass on the other three language templates. Same guarantees as
go/: survive server restart, client restart, half-open TCP, and long
outages; rejoin and drain prime-side backlog on reconnect, without
the user writing any of this in process.*.

python/main.py:
- grpc.keepalive_time_ms=10000, keepalive_timeout_ms=3000,
  keepalive_permit_without_calls=1 on the channel. Half-open TCP is
  detected within ~13s instead of the OS default ~2h.
- Exponential backoff with jitter; max_backoff_seconds config ceiling
  (default 120). Attempts counter resets after a session runs
  healthy for 60s so transient restarts don't escalate the delay.
- chain_id added as a required config field and sent as the
  x-chain-id gRPC metadata header (prime rejects streams without it).

typescript/src/main.ts:
- Same keepalive options on the @grpc/grpc-js client.
- Same exponential backoff + jitter logic.
- chain_id added to Config + metadata.

bash/:
- Config + README updated. The bash template uses Python's main.py
  as its runtime, so the behavioural changes above flow through
  without a separate main per language.

Docs: each README gains a "Durability guarantees" section so contract
authors see the invariants without reading the runtime code.
2026-04-19 21:32:24 -04:00
2bc57c073d go: keepalive, exponential backoff, chain_id metadata, durability guarantees
Three related fixes that turn the go template into a client that
survives the full matrix of server restart, client restart, network
blip, half-open TCP, and long outages (hours → months) — without the
user writing a line of reconnect logic in process.go.

1. gRPC keepalive: Time=10s, Timeout=3s, PermitWithoutStream=true.
   Half-open TCP (silent server restart, resumed laptop, NAT drop)
   is detected within ~13s. Previously the OS TCP keepalive took
   ~2h to notice, leaving the client as a ghost stream while prime
   logged "no active gRPC connection" for every skipped transaction.

2. Exponential backoff with jitter on reconnect. Effective delay =
   min(max_backoff_seconds, reconnect_delay_seconds * 2^attempts)
   + random(0, reconnect_delay_seconds). The attempts counter resets
   after any session that runs healthy for 60+ seconds. Jitter
   desynchronises clients so a server restart doesn't trigger a
   thundering herd. New max_backoff_seconds config field, default 120.

3. Unified error signalling: the sender goroutine now tears down the
   stream's context when it hits a Send error. Previously only Recv
   errors triggered a reconnect — a stale stream where only Send was
   broken could sit there indefinitely.

Also: chain_id is a required config field now and goes in the
x-chain-id gRPC metadata header alongside x-api-key and
x-smart-contract-id. Prime rejects streams without it with "missing
chain ID", which was silently breaking every template-based client
until users discovered it the hard way. README documents the
durability contract so contract authors know they don't have to
reimplement any of it.
2026-04-19 21:23:47 -04:00
0634e66469 Initial commit: smart contract templates for bash, go, python, and typescript 2026-03-17 19:59:47 -04:00