@@ -28,6 +28,7 @@ use hyper_timeout::TimeoutConnector;
28
28
use rustls:: ClientConfig ;
29
29
use tokio:: io:: AsyncRead ;
30
30
use tokio:: io:: AsyncWrite ;
31
+ use tokio:: sync:: Semaphore ;
31
32
use tokio_rustls:: TlsConnector ;
32
33
33
34
use super :: HttpClient ;
@@ -66,6 +67,7 @@ pub struct HttpClientBuilder {
66
67
supports_vpnless : bool ,
67
68
http2 : bool ,
68
69
timeout_config : Option < TimeoutConfig > ,
70
+ max_concurrent_requests : usize ,
69
71
}
70
72
71
73
impl HttpClientBuilder {
@@ -104,6 +106,10 @@ impl HttpClientBuilder {
104
106
supports_vpnless : false ,
105
107
http2 : true ,
106
108
timeout_config : None ,
109
+ // Semi-arbitrary sensible default: big enough to ensure good utilization of a typical
110
+ // internet link, small enough that we won't run out of FDs or make a server think we're
111
+ // DoSing them.
112
+ max_concurrent_requests : 32 ,
107
113
} )
108
114
}
109
115
@@ -214,6 +220,11 @@ impl HttpClientBuilder {
214
220
self . supports_vpnless
215
221
}
216
222
223
+ pub fn with_max_concurrent_requests ( & mut self , max_concurrent_requests : usize ) -> & mut Self {
224
+ self . max_concurrent_requests = max_concurrent_requests;
225
+ self
226
+ }
227
+
217
228
fn build_inner ( & self ) -> Arc < dyn RequestClient > {
218
229
match ( self . proxies . as_slice ( ) , & self . timeout_config ) {
219
230
// Construct x2p unix socket client.
@@ -294,6 +305,7 @@ impl HttpClientBuilder {
294
305
supports_vpnless : self . supports_vpnless ,
295
306
http2 : self . http2 ,
296
307
stats : HttpNetworkStats :: new ( ) ,
308
+ concurrent_requests_budget : Arc :: new ( Semaphore :: new ( self . max_concurrent_requests ) ) ,
297
309
}
298
310
}
299
311
}
0 commit comments