diff --git a/crates/factor-outbound-http/src/lib.rs b/crates/factor-outbound-http/src/lib.rs index 0170123b17..4fc368de55 100644 --- a/crates/factor-outbound-http/src/lib.rs +++ b/crates/factor-outbound-http/src/lib.rs @@ -50,11 +50,13 @@ impl Factor for OutboundHttpFactor { &self, mut ctx: ConfigureAppContext, ) -> anyhow::Result { + let connection_pooling = ctx + .take_runtime_config() + .unwrap_or_default() + .connection_pooling; Ok(AppState { - connection_pooling: ctx - .take_runtime_config() - .unwrap_or_default() - .connection_pooling, + wasi_http_clients: wasi::HttpClients::new(connection_pooling), + connection_pooling, }) } @@ -74,7 +76,7 @@ impl Factor for OutboundHttpFactor { self_request_origin: None, request_interceptor: None, spin_http_client: None, - wasi_http_clients: None, + wasi_http_clients: ctx.app_state().wasi_http_clients.clone(), connection_pooling: ctx.app_state().connection_pooling, }) } @@ -88,9 +90,16 @@ pub struct InstanceState { self_request_origin: Option, request_interceptor: Option>, // Connection-pooling client for 'fermyon:spin/http' interface + // + // TODO: We could move this to `AppState` to like the + // `wasi:http/outgoing-handler` pool for consistency, although it's probably + // not a high priority given that `fermyon:spin/http` is deprecated anyway. spin_http_client: Option, - // Connection pooling client for `wasi:http/outgoing-handler` interface - wasi_http_clients: Option, + // Connection pooling clients for `wasi:http/outgoing-handler` interface + // + // This is a clone of `AppState::wasi_http_clients`, meaning it is shared + // among all instances of the app. + wasi_http_clients: wasi::HttpClients, connection_pooling: bool, } @@ -171,5 +180,7 @@ impl std::fmt::Display for SelfRequestOrigin { } pub struct AppState { + // Connection pooling clients for `wasi:http/outgoing-handler` interface + wasi_http_clients: wasi::HttpClients, connection_pooling: bool, } diff --git a/crates/factor-outbound-http/src/wasi.rs b/crates/factor-outbound-http/src/wasi.rs index 68cbac3b91..312382bc2f 100644 --- a/crates/factor-outbound-http/src/wasi.rs +++ b/crates/factor-outbound-http/src/wasi.rs @@ -101,6 +101,23 @@ pub(super) struct HttpClients { https: HttpsClient, } +impl HttpClients { + pub(super) fn new(enable_pooling: bool) -> Self { + let builder = move || { + let mut builder = Client::builder(TokioExecutor::new()); + if !enable_pooling { + builder.pool_max_idle_per_host(0); + } + builder + }; + Self { + http1: builder().build(HttpConnector), + http2: builder().http2_only(true).build(HttpConnector), + https: builder().build(HttpsConnector), + } + } +} + pub(crate) struct WasiHttpImplInner<'a> { state: &'a mut InstanceState, table: &'a mut ResourceTable, @@ -135,25 +152,6 @@ impl WasiHttpView for WasiHttpImplInner<'_> { request: Request, config: wasmtime_wasi_http::types::OutgoingRequestConfig, ) -> wasmtime_wasi_http::HttpResult { - let connection_pooling = self.state.connection_pooling; - let builder = move || { - let mut builder = Client::builder(TokioExecutor::new()); - if !connection_pooling { - builder.pool_max_idle_per_host(0); - } - builder - }; - - let http_clients = self - .state - .wasi_http_clients - .get_or_insert_with(|| HttpClients { - http1: builder().build(HttpConnector), - http2: builder().http2_only(true).build(HttpConnector), - https: builder().build(HttpsConnector), - }) - .clone(); - Ok(HostFutureIncomingResponse::Pending( wasmtime_wasi::runtime::spawn( send_request_impl( @@ -164,7 +162,7 @@ impl WasiHttpView for WasiHttpImplInner<'_> { self.state.request_interceptor.clone(), self.state.self_request_origin.clone(), self.state.blocked_networks.clone(), - http_clients, + self.state.wasi_http_clients.clone(), ) .in_current_span(), ),