3636import com .linecorp .bot .client .base .http .HttpResponse ;
3737import com .linecorp .bot .jackson .ModelObjectMapper ;
3838
39+ import okhttp3 .Dispatcher ;
3940import okhttp3 .Interceptor ;
4041import okhttp3 .OkHttpClient ;
4142import okhttp3 .Request ;
@@ -92,6 +93,10 @@ public ApiClientBuilder(URI apiEndPoint, Class<T> clientClass, ExceptionBuilder
9293
9394 private HttpAuthenticator proxyAuthenticator ;
9495
96+ private Integer maxRequests = 64 ;
97+
98+ private Integer maxRequestsPerHost = 5 ;
99+
95100 /**
96101 * API Endpoint.
97102 */
@@ -134,6 +139,25 @@ public ApiClientBuilder<T> addInterceptor(HttpInterceptor interceptor) {
134139 return this ;
135140 }
136141
142+ /**
143+ * The maximum number of requests to execute concurrently.
144+ * Default: 64
145+ */
146+ public ApiClientBuilder <T > maxRequests (Integer maxRequests ) {
147+ this .maxRequests = maxRequests ;
148+ return this ;
149+ }
150+
151+ /**
152+ * The maximum number of requests for each host to execute concurrently.
153+ * Default: 5
154+ */
155+ // https://square.github.io/okhttp/4.x/okhttp/okhttp3/-dispatcher/max-requests-per-host/
156+ public ApiClientBuilder <T > maxRequestsPerHost (Integer maxRequestsPerHost ) {
157+ this .maxRequestsPerHost = maxRequestsPerHost ;
158+ return this ;
159+ }
160+
137161 private static Interceptor buildLoggingInterceptor () {
138162 final Logger slf4jLogger = LoggerFactory .getLogger ("com.linecorp.bot.client.wire" );
139163
@@ -151,11 +175,21 @@ public ApiClientBuilder<T> proxyAuthenticator(HttpAuthenticator proxyAuthenticat
151175 return this ;
152176 }
153177
178+ // visible for testing
179+ OkHttpClient .Builder createBuilder () {
180+ return new OkHttpClient .Builder ();
181+ }
182+
183+ // visible for testing
184+ Dispatcher createDispatcher () {
185+ return new Dispatcher ();
186+ }
187+
154188 /**
155189 * Creates a new Client.
156190 */
157191 public T build () {
158- OkHttpClient .Builder okHttpClientBuilder = new OkHttpClient . Builder ();
192+ OkHttpClient .Builder okHttpClientBuilder = createBuilder ();
159193 additionalInterceptors .forEach (okHttpClientBuilder ::addInterceptor );
160194 okHttpClientBuilder .addInterceptor (buildLoggingInterceptor ());
161195
@@ -165,6 +199,12 @@ public T build() {
165199 .readTimeout (readTimeout )
166200 .writeTimeout (writeTimeout );
167201
202+ // configure dispatcher
203+ Dispatcher dispatcher = createDispatcher ();
204+ dispatcher .setMaxRequests (maxRequests );
205+ dispatcher .setMaxRequestsPerHost (maxRequestsPerHost );
206+ okHttpClientBuilder .dispatcher (dispatcher );
207+
168208 // Error handling.
169209 okHttpClientBuilder .addInterceptor (chain -> {
170210 Request request = chain .request ();
@@ -197,13 +237,19 @@ public T build() {
197237 return retrofit .create (clientClass );
198238 }
199239
240+ @ Override
200241 public String toString () {
201- return "ApiClientBuilder(clientClass=" + this .clientClass
202- + ", apiEndPoint=" + this .apiEndPoint
203- + ", connectTimeout=" + this .connectTimeout
204- + ", readTimeout=" + this .readTimeout
205- + ", writeTimeout=" + this .writeTimeout
206- + ", additionalInterceptors=" + this .additionalInterceptors
207- + ")" ;
242+ return "ApiClientBuilder{"
243+ + "objectMapper=" + objectMapper
244+ + ", clientClass=" + clientClass
245+ + ", exceptionBuilder=" + exceptionBuilder
246+ + ", apiEndPoint=" + apiEndPoint
247+ + ", connectTimeout=" + connectTimeout
248+ + ", readTimeout=" + readTimeout
249+ + ", writeTimeout=" + writeTimeout
250+ + ", additionalInterceptors=" + additionalInterceptors
251+ + ", maxRequests=" + maxRequests
252+ + ", maxRequestsPerHost=" + maxRequestsPerHost
253+ + '}' ;
208254 }
209255}
0 commit comments