Commit 78b6338
feat: configurable timeouts and concurrency with lenient defaults for high-burst workloads (#14)
## Summary
- Expose `connectionTimeout`, `connectionAcquireTimeout`,
`subscriptionTimeout`, and `maxConcurrency` on
`SageMakerConfig.Builder`. Each is validated `> 0` / non-null at build
time. Public `DEFAULT_*` constants on `SageMakerConfig` document the
chosen defaults.
- Wire them through `SageMakerTransportFactory` (Netty
`connectionTimeout` / `connectionAcquisitionTimeout` / `maxConcurrency`)
and `SageMakerTransport` (input-publisher subscription wait at
`ensureConnected()`).
- Move defaults to values tuned for high-burst workloads instead of
inheriting the AWS Netty defaults, which fail-fast in a way that's
actively wrong for SageMaker bidi streaming under bursts.
| Knob | Old default | New default | Why |
|---|---|---|---|
| `connectionTimeout` | AWS Netty default = 2 s | **30 s** | Cold-start
endpoints under a 200–500-stream burst can't accept TLS handshakes in 2
s |
| `connectionAcquireTimeout` | AWS Netty default = 10 s | **60 s** | A
400-stream burst drains the acquire pool past 10 s |
| `subscriptionTimeout` | (was hardcoded 30 s) | **60 s** | Slow
first-stream subscribe under burst |
| `maxConcurrency` | (was hardcoded 500) | **500** (now tunable) | No
change — just made it tunable |
## Why this matters
Empirically validated against a 400-concurrent-stream burst test on a
10× `ml.g6.2xlarge` endpoint, replicating a customer report:
| Error category | Before (Maven Central 0.1.2 + AWS defaults) | After
(this PR) |
|---|---:|---:|
| `Connection pool exhausted (Acquire took longer)` | 3,230 | ~0 |
| `TCP connect timed out` | 706 | ~0 |
| `TCP Connection reset` | 3,528 | sharply down |
Out of the box, callers no longer have to know that AWS's
general-purpose Netty defaults bite hard on the SageMaker streaming
path; the transport ships sane-for-its-use-case defaults. Anyone who
wants fail-fast behavior can tighten the knobs explicitly:
```java
SageMakerConfig config = SageMakerConfig.builder()
.endpointName("my-deepgram-endpoint")
.region("us-east-2")
.connectionTimeout(Duration.ofSeconds(5))
.connectionAcquireTimeout(Duration.ofSeconds(15))
.build();
```
## Scope and what this does NOT fix
This PR addresses the transport layer only. The SDK-level retry storm in
`com.deepgram:deepgram-java-sdk` (the hardcoded
`connectionFuture.get(4000, MILLISECONDS)` in
`ReconnectingWebSocketListener.connect()` plus the listener's default
`maxRetries = Integer.MAX_VALUE`) is not touched here and was
empirically observed to remain even with this PR's transport fixes — the
bottleneck simply moves inward to the SDK ceiling.
The full burst-handling fix requires pairing this PR with the
corresponding change in `deepgram-java-sdk` that auto-disables
`ReconnectingWebSocketListener` when a custom transport is configured
(`ClientOptions.reconnect(false)` + auto-set in
`DeepgramClientBuilder.transportFactory(...)`). With both layers in
place, end-to-end error counts drop ~97 % at 400 concurrent streams.
## Backwards compatibility
Adds new builder methods only; no existing API is removed or modified.
Existing callers using
`SageMakerConfig.builder().endpointName(...).region(...).build()` get
the new defaults automatically — same calling convention, more lenient
runtime behavior. No code changes required for existing applications.
## Test plan
- [x] `./gradlew :sagemaker-transport:test` — all tests pass (18/18; 4
new tests for defaults, custom values, and validation of non-positive
arguments).
- [x] Local build of the patched JAR consumed by a load-test harness
against a real SageMaker endpoint.
- [x] Validation run vs. baseline measured a `Connection pool exhausted`
/ `TCP connect timed out` reduction to ~0.
- [ ] CI passes.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Greg Holmes <greg.holmes@deepgram.com>1 parent a25bf11 commit 78b6338
10 files changed
Lines changed: 1792 additions & 86 deletions
File tree
- examples/src/main/java/com/deepgram/examples
- sagemaker-transport
- src
- main/java/com/deepgram/sagemaker
- test/java/com/deepgram/sagemaker
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
14 | | - | |
| 14 | + | |
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
| |||
29 | 29 | | |
30 | 30 | | |
31 | 31 | | |
32 | | - | |
| 32 | + | |
33 | 33 | | |
34 | 34 | | |
35 | 35 | | |
| |||
95 | 95 | | |
96 | 96 | | |
97 | 97 | | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
98 | 107 | | |
99 | 108 | | |
100 | 109 | | |
| |||
103 | 112 | | |
104 | 113 | | |
105 | 114 | | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
106 | 197 | | |
107 | 198 | | |
108 | 199 | | |
| |||
Lines changed: 3 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| 11 | + | |
11 | 12 | | |
12 | 13 | | |
13 | 14 | | |
| |||
85 | 86 | | |
86 | 87 | | |
87 | 88 | | |
88 | | - | |
| 89 | + | |
89 | 90 | | |
90 | 91 | | |
91 | | - | |
| 92 | + | |
92 | 93 | | |
93 | 94 | | |
94 | 95 | | |
| |||
Lines changed: 2 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| 12 | + | |
12 | 13 | | |
13 | 14 | | |
14 | 15 | | |
| |||
100 | 101 | | |
101 | 102 | | |
102 | 103 | | |
103 | | - | |
| 104 | + | |
104 | 105 | | |
105 | 106 | | |
106 | 107 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
69 | 69 | | |
70 | 70 | | |
71 | 71 | | |
72 | | - | |
| 72 | + | |
73 | 73 | | |
74 | 74 | | |
75 | 75 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| |||
0 commit comments