Skip to content

Commit 7df3d2a

Browse files
committed
add high-throughput http client tuning
1 parent 9872045 commit 7df3d2a

6 files changed

Lines changed: 472 additions & 33 deletions

File tree

DOCS.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,44 @@ You can override this behavior by explicitly passing in the API key and secret a
5555
var properties = new Properties();
5656
properties.put(DefaultClient.API_KEY_PROP_NAME, "<api-key>");
5757
properties.put(DefaultClient.API_SECRET_PROP_NAME, "<api-secret>");
58+
properties.put(DefaultClient.DISPATCHER_MAX_REQUESTS_PROP_NAME, "128");
59+
properties.put(DefaultClient.DISPATCHER_MAX_REQUESTS_PER_HOST_PROP_NAME, "32");
5860
properties.put(DefaultClient.CONNECTION_POOL_MAX_IDLE_CONNECTIONS_PROP_NAME, "20");
61+
properties.put(DefaultClient.CONNECTION_POOL_KEEP_ALIVE_DURATION_PROP_NAME, "59000");
62+
properties.put(DefaultClient.API_CONNECT_TIMEOUT_PROP_NAME, "10000");
63+
properties.put(DefaultClient.API_READ_TIMEOUT_PROP_NAME, "30000");
64+
properties.put(DefaultClient.API_WRITE_TIMEOUT_PROP_NAME, "30000");
65+
properties.put(DefaultClient.API_TIMEOUT_PROP_NAME, "30000");
5966
var client = new DefaultClient(properties);
67+
client.setDispatcher(128, 32);
6068
client.setConnectionPool(20, Duration.ofSeconds(59));
69+
client.setTimeouts(
70+
Duration.ofSeconds(10),
71+
Duration.ofSeconds(30),
72+
Duration.ofSeconds(30),
73+
Duration.ofSeconds(30));
6174
DefaultClient.setInstance(client);
6275
```
6376

77+
You can also pass the same configuration through explicit HTTP options:
78+
79+
```java
80+
var options =
81+
DefaultClient.HttpClientOptions.builder()
82+
.dispatcher(128, 32)
83+
.connectionPool(20, Duration.ofSeconds(59))
84+
.connectTimeout(Duration.ofSeconds(10))
85+
.readTimeout(Duration.ofSeconds(30))
86+
.writeTimeout(Duration.ofSeconds(30))
87+
.callTimeout(Duration.ofSeconds(30))
88+
.build();
89+
90+
var client = new DefaultClient(properties, options);
91+
```
92+
93+
For high traffic workloads, `dispatcher.maxRequests` and
94+
`dispatcher.maxRequestsPerHost` are usually the first values to tune.
95+
6496
### Simple Example
6597
**Synchronous:**
6698

README.md

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,15 @@ To configure the SDK you need to provide required properties
130130
| --------------------------- | ------------------- | ------------------------------ | -------- |
131131
| io.getstream.chat.apiKey | STREAM_KEY | - | Yes |
132132
| io.getstream.chat.apiSecret | STREAM_SECRET | - | Yes |
133-
| io.getstream.chat.timeout | STREAM_CHAT_TIMEOUT | 10000 | No |
133+
| io.getstream.chat.timeout | STREAM_CHAT_TIMEOUT | 20000 | No |
134+
| io.getstream.chat.connectTimeout | STREAM_CHAT_CONNECT_TIMEOUT | 20000 | No |
135+
| io.getstream.chat.readTimeout | STREAM_CHAT_READ_TIMEOUT | 20000 | No |
136+
| io.getstream.chat.writeTimeout | STREAM_CHAT_WRITE_TIMEOUT | 20000 | No |
134137
| io.getstream.chat.url | STREAM_CHAT_URL | https://chat.stream-io-api.com | No |
135-
| io.getstream.chat.connectionPool.maxIdleConnections | STREAM_CHAT_CONNECTION_POOL_MAX_IDLE_CONNECTIONS | 5 | No |
136-
| io.getstream.chat.connectionPool.keepAliveDurationMs | STREAM_CHAT_CONNECTION_POOL_KEEP_ALIVE_DURATION_MS | 59000 | No |
138+
| io.getstream.chat.connectionPool.maxIdleConnections | STREAM_CHAT_CONNECTION_POOL_MAX_IDLE_CONNECTIONS | 10 | No |
139+
| io.getstream.chat.connectionPool.keepAliveDurationMs | STREAM_CHAT_CONNECTION_POOL_KEEP_ALIVE_DURATION_MS | 118000 | No |
140+
| io.getstream.chat.dispatcher.maxRequests | STREAM_CHAT_DISPATCHER_MAX_REQUESTS | 128 | No |
141+
| io.getstream.chat.dispatcher.maxRequestsPerHost | STREAM_CHAT_DISPATCHER_MAX_REQUESTS_PER_HOST | 10 | No |
137142

138143
You can also use your own CDN by creating an implementation of FileHandler and setting it this way
139144

@@ -149,14 +154,61 @@ You can also tune the underlying OkHttp connection pool explicitly:
149154
var properties = new Properties();
150155
properties.put(DefaultClient.API_KEY_PROP_NAME, "<api-key>");
151156
properties.put(DefaultClient.API_SECRET_PROP_NAME, "<api-secret>");
157+
properties.put(DefaultClient.DISPATCHER_MAX_REQUESTS_PROP_NAME, "128");
158+
properties.put(DefaultClient.DISPATCHER_MAX_REQUESTS_PER_HOST_PROP_NAME, "32");
152159
properties.put(DefaultClient.CONNECTION_POOL_MAX_IDLE_CONNECTIONS_PROP_NAME, "20");
153160
properties.put(DefaultClient.CONNECTION_POOL_KEEP_ALIVE_DURATION_PROP_NAME, "59000");
161+
properties.put(DefaultClient.API_CONNECT_TIMEOUT_PROP_NAME, "10000");
162+
properties.put(DefaultClient.API_READ_TIMEOUT_PROP_NAME, "30000");
163+
properties.put(DefaultClient.API_WRITE_TIMEOUT_PROP_NAME, "30000");
164+
properties.put(DefaultClient.API_TIMEOUT_PROP_NAME, "30000");
154165

155166
var client = new DefaultClient(properties);
167+
client.setDispatcher(128, 32);
156168
client.setConnectionPool(20, Duration.ofSeconds(59));
169+
client.setTimeouts(
170+
Duration.ofSeconds(10),
171+
Duration.ofSeconds(30),
172+
Duration.ofSeconds(30),
173+
Duration.ofSeconds(30));
157174
DefaultClient.setInstance(client);
158175
```
159176

177+
Or configure the same values through options:
178+
179+
```java
180+
var options =
181+
DefaultClient.HttpClientOptions.builder()
182+
.dispatcher(128, 32)
183+
.connectionPool(20, Duration.ofSeconds(59))
184+
.connectTimeout(Duration.ofSeconds(10))
185+
.readTimeout(Duration.ofSeconds(30))
186+
.writeTimeout(Duration.ofSeconds(30))
187+
.callTimeout(Duration.ofSeconds(30))
188+
.build();
189+
190+
var client = new DefaultClient(properties, options);
191+
```
192+
193+
### High traffic
194+
195+
For high traffic backends, a good starting point is:
196+
197+
```java
198+
var options =
199+
DefaultClient.HttpClientOptions.builder()
200+
.dispatcher(128, 32)
201+
.connectionPool(20, Duration.ofSeconds(59))
202+
.connectTimeout(Duration.ofSeconds(10))
203+
.readTimeout(Duration.ofSeconds(30))
204+
.writeTimeout(Duration.ofSeconds(30))
205+
.callTimeout(Duration.ofSeconds(30))
206+
.build();
207+
```
208+
209+
Start there and load test. In practice, `dispatcher.maxRequests` and
210+
`dispatcher.maxRequestsPerHost` usually affect throughput more than connection-pool size.
211+
160212
## Print Chat app configuration
161213

162214
<table>

src/main/java/io/getstream/chat/java/services/framework/Client.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ public interface Client {
1919

2020
void setTimeout(@NotNull Duration timeoutDuration);
2121

22-
void setConnectionPool(int maxIdleConnections, @NotNull Duration keepAliveDuration);
23-
2422
static Client getInstance() {
2523
return DefaultClient.getInstance();
2624
}

0 commit comments

Comments
 (0)