@@ -22,6 +22,7 @@ use spin_factors::{
22
22
anyhow, ConfigureAppContext , Factor , FactorData , PrepareContext , RuntimeFactors ,
23
23
SelfInstanceBuilder ,
24
24
} ;
25
+ use tokio:: sync:: Semaphore ;
25
26
use wasmtime_wasi_http:: WasiHttpCtx ;
26
27
27
28
pub use wasmtime_wasi_http:: {
@@ -51,13 +52,15 @@ impl Factor for OutboundHttpFactor {
51
52
& self ,
52
53
mut ctx : ConfigureAppContext < T , Self > ,
53
54
) -> anyhow:: Result < Self :: AppState > {
54
- let connection_pooling = ctx
55
- . take_runtime_config ( )
56
- . unwrap_or_default ( )
57
- . connection_pooling ;
55
+ let config = ctx. take_runtime_config ( ) . unwrap_or_default ( ) ;
58
56
Ok ( AppState {
59
- wasi_http_clients : wasi:: HttpClients :: new ( connection_pooling) ,
60
- connection_pooling,
57
+ wasi_http_clients : wasi:: HttpClients :: new ( config. connection_pooling_enabled ) ,
58
+ connection_pooling_enabled : config. connection_pooling_enabled ,
59
+ concurrent_outbound_requests_semaphore : config
60
+ . max_concurrent_requests
61
+ // Permit count is the max concurrent requests + 1.
62
+ // i.e., 0 concurrent requests means 1 total request.
63
+ . map ( |n| Arc :: new ( Semaphore :: new ( n + 1 ) ) ) ,
61
64
} )
62
65
}
63
66
@@ -78,7 +81,11 @@ impl Factor for OutboundHttpFactor {
78
81
request_interceptor : None ,
79
82
spin_http_client : None ,
80
83
wasi_http_clients : ctx. app_state ( ) . wasi_http_clients . clone ( ) ,
81
- connection_pooling : ctx. app_state ( ) . connection_pooling ,
84
+ connection_pooling_enabled : ctx. app_state ( ) . connection_pooling_enabled ,
85
+ concurrent_outbound_requests_semaphore : ctx
86
+ . app_state ( )
87
+ . concurrent_outbound_requests_semaphore
88
+ . clone ( ) ,
82
89
} )
83
90
}
84
91
}
@@ -92,7 +99,7 @@ pub struct InstanceState {
92
99
request_interceptor : Option < Arc < dyn OutboundHttpInterceptor > > ,
93
100
// Connection-pooling client for 'fermyon:spin/http' interface
94
101
//
95
- // TODO: We could move this to `AppState` to like the
102
+ // TODO: We could move this to `AppState` like the
96
103
// `wasi:http/outgoing-handler` pool for consistency, although it's probably
97
104
// not a high priority given that `fermyon:spin/http` is deprecated anyway.
98
105
spin_http_client : Option < reqwest:: Client > ,
@@ -101,7 +108,10 @@ pub struct InstanceState {
101
108
// This is a clone of `AppState::wasi_http_clients`, meaning it is shared
102
109
// among all instances of the app.
103
110
wasi_http_clients : wasi:: HttpClients ,
104
- connection_pooling : bool ,
111
+ /// Whether connection pooling is enabled for this instance.
112
+ connection_pooling_enabled : bool ,
113
+ /// A semaphore to limit the number of concurrent outbound requests.
114
+ concurrent_outbound_requests_semaphore : Option < Arc < Semaphore > > ,
105
115
}
106
116
107
117
impl InstanceState {
@@ -183,5 +193,8 @@ impl std::fmt::Display for SelfRequestOrigin {
183
193
pub struct AppState {
184
194
// Connection pooling clients for `wasi:http/outgoing-handler` interface
185
195
wasi_http_clients : wasi:: HttpClients ,
186
- connection_pooling : bool ,
196
+ /// Whether connection pooling is enabled for this app.
197
+ connection_pooling_enabled : bool ,
198
+ /// A semaphore to limit the number of concurrent outbound requests.
199
+ concurrent_outbound_requests_semaphore : Option < Arc < Semaphore > > ,
187
200
}
0 commit comments