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