You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: Add reset() method, gRPC keep-alive, and transport resilience
- Add public reset() method to SpiceClient for recovering from
unrecoverable transport failures (SSL cert mismatch, persistent
UNAVAILABLE errors, stale connections pinned to wrong backend IPs)
- Extract buildFlightClient() for reuse during construction and reset
- Configure HTTP/2 keep-alive (30s interval, 10s timeout) on the
gRPC channel to detect dead/idle connections behind load balancers
- Add ensureFlightClient() guard in queryInternal() for safety
- Handle null flightClient in close() after reset
- Add ResetTest.java with 20 unit tests covering happy path, edge
cases, concurrency, construction variants, and integration
- Document transport resilience and reset() usage in README
The `SpiceClient` is designed for long-lived reuse. The underlying gRPC channel uses `dns:///` resolution, which periodically re-resolves hostnames so clients automatically recover from load-balancer IP rotation (e.g. AWS NLB). HTTP/2 keep-alive is enabled by default (30s interval, 10s timeout) to detect dead connections quickly.
219
+
220
+
For the rare case where the transport becomes permanently stuck (e.g. TLS handshake to a wrong backend, persistent `UNAVAILABLE` after retries), use `reset()` to discard the bad connection and immediately establish a fresh one:
221
+
222
+
```java
223
+
SpiceClient client =SpiceClient.builder()
224
+
.withApiKey(API_KEY)
225
+
.withSpiceCloud()
226
+
.build();
227
+
228
+
// Long-lived usage with transport recovery
229
+
try {
230
+
FlightStream stream = client.query(sql);
231
+
// process results...
232
+
} catch (ExecutionException e) {
233
+
if (isTransportFailure(e.getCause())) {
234
+
client.reset(); // discard bad transport, reconnect immediately
235
+
FlightStream stream = client.query(sql); // no connection overhead
236
+
} else {
237
+
throw e;
238
+
}
239
+
}
240
+
```
241
+
242
+
**DNS cache TTL:** The gRPC `DnsNameResolver` respects the JVM's DNS cache TTL. For more aggressive DNS refresh (recommended for cloud-deployed clients), set the JVM property:
243
+
244
+
```bash
245
+
-Dnetworkaddress.cache.ttl=30
246
+
```
247
+
216
248
### Iterating Through Results
217
249
218
250
For more control over query results, you can iterate through rows and access individual field values:
0 commit comments