From c1686bbb3d8d67f3a05b167eccb0f7f18d1930a4 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 28 May 2026 12:37:28 -0700 Subject: [PATCH 1/2] Document concurrent instance reuse in `wasi:http/service` This commit adds a documentation block to the `wasi:http/service` world that's the result of discussions in today's WASI subgroup meeting, #918, and #919. The documentation here indicates a few properties around concurrent instance reuse, namely: * Guests should expect to be concurrently reused. If this is not acceptable then guests should disable reuse through backpressure mechanisms. * Guests should ensure that outgoing HTTP requests are done within the context of the original root task, or the original invocation of `handler`. If guests can't implement this then they're expected to use backpressure mechanisms instead. The overall conclusion of the various discussions that have happened over the past week or so is that it's not possible to provide the attribute behavior some hosts require exclusively through either in-guest interactions or pure-host interactions. Instead being able to reliably provide accurate attribution requires specifically outlining guidelines for both guests and hosts. The mechanism intended to be used for attribution is then: * For hosts such as Wasmtime calls to imports will be able to reflect on the current async call stack, notably the root export task. Hosts can then use this to correlate an identifier provided when a root task is created, providing a strong link from the import call to whatever export initiated it. This is expected to work as-is for some guest languages, such as Rust, but this is also not a bulletproof solution. Guests can always internally call imports from any currently-running task, and additionally languages such as JS and Go at this time are structured in such a way where imports are not always naturally called from the originating export task. * To enable languages like JS and Go to be able to leverage concurrent reuse while providing accurate attribution of outgoing requests to incoming requests, the plan is to eventually add and specify intrinsics on the component model level to, in a scoped fashion, mutate the async call stack. For example a guest would be able to say "I'm about to do some work for this component model task". When Wasmtime reflects on the async call graph at that time it'd see this and understand that the attribution needs to be slightly adjusted to what it would otherwise by default be. The goal with these addition is to enable hosts to be able to reliably expect to attribute outgoing requests to incoming requests (via async call graph inspection), provide guests the ability to work today (either naturally or disabling concurrent reuse via backpressure), and ensure that well-behaved and idiomatic guests can work reliably with concurrent reuse in the long-run (via component model intrinsics to massage the async backtrace that hosts operate with). When this is all combined it's expected to resolve the concerns of #918 and #919 with idiomatic bindings in guests and hosts alike. Closes #918 Closes #919 --- proposals/http/wit-0.3.0-draft/worlds.wit | 26 +++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/proposals/http/wit-0.3.0-draft/worlds.wit b/proposals/http/wit-0.3.0-draft/worlds.wit index 9917e054..6543db78 100644 --- a/proposals/http/wit-0.3.0-draft/worlds.wit +++ b/proposals/http/wit-0.3.0-draft/worlds.wit @@ -31,6 +31,32 @@ world service { /// /// This may also be used to receive synthesized or forwarded requests from /// another component. + /// + /// # Concurrent instance reuse + /// + /// Hosts may concurrently invoke this `handler` interface multiple times, + /// even when previous requests have yet to finish processing. This means that + /// the guest, if it blocks, may be required to service multiple requests at + /// the same time. Guests can opt-out of this behavior with component-model + /// backpressure to avoid sending more requests to this instance while a + /// previous one is being processed, however. + /// + /// Another requirement that hosts place on guests implementing this + /// interface, in addition to being able to concurrently invoke it, is that + /// the guest sends outgoing HTTP requests, via the `client` import above + /// or the `handler` import in the `middleware` world, in such a way that the + /// host can accurately attribute which invocation of `handler` induced the + /// outgoing HTTP request to be sent. This requirement enables embedders, + /// for example, to correctly implement the CDN-Loop header automatically and + /// ensure that outgoing requests correctly build on incoming requests. In + /// general this is not a hard requirement that embedders can rely on, but + /// well-behaved guests are expected to provide this guarantee. Hosts which + /// require a hard guarantee regardless of guest will not invoke `handler` + /// more than once concurrently. Guests which export `handler` are expected to + /// ensure that calls to imported interfaces happen on the same component + /// model task that the `handler` was originally invoked on. If guests cannot + /// provide this guarantee then they're expected to opt-out of concurrent + /// through the component model's backpressure mechanisms. export handler; } From 3e39a136b06a8a984930104fba238dc5fdb8c8f2 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 1 Jun 2026 07:08:47 -0700 Subject: [PATCH 2/2] Review comments --- proposals/http/wit-0.3.0-draft/worlds.wit | 46 +++++++++++++---------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/proposals/http/wit-0.3.0-draft/worlds.wit b/proposals/http/wit-0.3.0-draft/worlds.wit index 6543db78..6c581d56 100644 --- a/proposals/http/wit-0.3.0-draft/worlds.wit +++ b/proposals/http/wit-0.3.0-draft/worlds.wit @@ -36,27 +36,33 @@ world service { /// /// Hosts may concurrently invoke this `handler` interface multiple times, /// even when previous requests have yet to finish processing. This means that - /// the guest, if it blocks, may be required to service multiple requests at - /// the same time. Guests can opt-out of this behavior with component-model - /// backpressure to avoid sending more requests to this instance while a - /// previous one is being processed, however. + /// the guest, if it becomes idle while being blocked on I/O, may be required + /// to service multiple requests at the same time. Guests can opt-out of + /// this behavior with component-model backpressure to avoid sending more + /// requests to this instance while a previous one is being processed, + /// however. /// - /// Another requirement that hosts place on guests implementing this - /// interface, in addition to being able to concurrently invoke it, is that - /// the guest sends outgoing HTTP requests, via the `client` import above - /// or the `handler` import in the `middleware` world, in such a way that the - /// host can accurately attribute which invocation of `handler` induced the - /// outgoing HTTP request to be sent. This requirement enables embedders, - /// for example, to correctly implement the CDN-Loop header automatically and - /// ensure that outgoing requests correctly build on incoming requests. In - /// general this is not a hard requirement that embedders can rely on, but - /// well-behaved guests are expected to provide this guarantee. Hosts which - /// require a hard guarantee regardless of guest will not invoke `handler` - /// more than once concurrently. Guests which export `handler` are expected to - /// ensure that calls to imported interfaces happen on the same component - /// model task that the `handler` was originally invoked on. If guests cannot - /// provide this guarantee then they're expected to opt-out of concurrent - /// through the component model's backpressure mechanisms. + /// In some contexts, correct attribution of resource usage and I/O operations + /// is an important requirement. For example, correct implementation of the + /// CDN-Loop header in the context of a proxy server requires that outgoing + /// HTTP requests can be attributed to the incoming HTTP request that induced + /// them. + /// + /// Hosts with this requirement must associate work happening on the same + /// component model task that the `handler` was originally invoked on with the + /// same incoming HTTP request. + /// + /// Conversely, guests must ensure that calls to imported interfaces happen on + /// the same component model task that the `handler` was originally invoked + /// on. Guest runtime implementations that do not provide this guarantee are + /// expected to opt-out of concurrent through the component model's + /// backpressure mechanisms. + /// + /// Note that hosts can't rely on this guarantee being upheld by all guests, + /// and shouldn't treat it as part of their security model. Instead, the + /// combination of the above host and guest requirements enable hosts to + /// enforce correctness properties on behalf of the overall system a guest is + /// part of. export handler; }