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.
This commit is contained in:
@@ -40,6 +40,7 @@ This template uses a thin Python gRPC infrastructure layer to handle the network
|
||||
4. **Configure your connection** by editing `config.yaml`:
|
||||
```yaml
|
||||
server_address: "your-dragonchain-server:50051"
|
||||
chain_id: "your-chain-public-id"
|
||||
smart_contract_id: "your-smart-contract-id"
|
||||
api_key: "your-api-key"
|
||||
```
|
||||
@@ -56,13 +57,24 @@ This template uses a thin Python gRPC infrastructure layer to handle the network
|
||||
| Field | Description | Default |
|
||||
|-------|-------------|---------|
|
||||
| `server_address` | gRPC server address | Required |
|
||||
| `chain_id` | Public chain id the SC is registered on (sent as `x-chain-id` metadata) | Required |
|
||||
| `smart_contract_id` | Your smart contract ID | Required |
|
||||
| `api_key` | API key for authentication | Required |
|
||||
| `use_tls` | Enable TLS encryption | `false` |
|
||||
| `tls_cert_path` | Path to TLS certificate | - |
|
||||
| `num_workers` | Concurrent transaction processors | `10` |
|
||||
| `reconnect_delay_seconds` | Delay between reconnection attempts | `5` |
|
||||
| `max_reconnect_attempts` | Max reconnect attempts (0 = infinite) | `0` |
|
||||
| `reconnect_delay_seconds` | Base delay for exponential backoff between reconnect attempts | `3` |
|
||||
| `max_backoff_seconds` | Ceiling for the exponential backoff | `120` |
|
||||
| `max_reconnect_attempts` | Max reconnect attempts (0 = infinite, recommended) | `0` |
|
||||
|
||||
## Durability guarantees (provided by the Python `main.py` runtime, no work for you)
|
||||
|
||||
- **Server restart, update, crash, or network blip** → the runtime auto-reconnects and resumes processing. Transactions observed while the stream was down stay queued on the Dragonchain Prime side and are delivered (oldest first) on reconnect.
|
||||
- **Client restart or long outage** → when this process comes back up (minutes, hours, months later), it rejoins the stream and prime re-delivers every still-pending transaction that should have invoked it.
|
||||
- **Half-open TCP** (silent peer, resumed laptop, corporate NAT dropping idle flows) is detected within ~13 seconds via gRPC keepalive and triggers a reconnect. No dangling ghost streams.
|
||||
- **Reconnect storms** are avoided: exponential backoff with jitter means many clients reconnecting after a server restart don't all slam `accept()` at the same instant.
|
||||
|
||||
These are invariants of the runtime — you do not add any of this in `process.sh`.
|
||||
|
||||
## Implementing Your Smart Contract
|
||||
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
# The gRPC server address to connect to
|
||||
server_address: "localhost:50051"
|
||||
|
||||
# The public chain id on which this smart contract is registered.
|
||||
# Sent as the x-chain-id gRPC metadata header — prime rejects streams
|
||||
# without it.
|
||||
chain_id: "your-chain-public-id"
|
||||
|
||||
# Your smart contract ID (provided by Dragonchain)
|
||||
smart_contract_id: "your-smart-contract-id"
|
||||
|
||||
@@ -19,6 +24,12 @@ use_tls: false
|
||||
# Number of worker threads for processing transactions concurrently
|
||||
num_workers: 10
|
||||
|
||||
# Reconnect settings
|
||||
reconnect_delay_seconds: 5
|
||||
# Reconnect settings. The client uses exponential backoff with jitter:
|
||||
# effective delay = min(max_backoff_seconds, reconnect_delay_seconds * 2^attempts) + random(0, reconnect_delay_seconds).
|
||||
# Keep max_reconnect_attempts at 0 (infinite) unless you have a specific
|
||||
# reason to stop — the client is designed to survive arbitrarily long
|
||||
# outages and resume processing from the prime-side queue when the
|
||||
# server returns.
|
||||
reconnect_delay_seconds: 3
|
||||
max_backoff_seconds: 120
|
||||
max_reconnect_attempts: 0 # 0 = infinite retries
|
||||
|
||||
Reference in New Issue
Block a user