Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lift http handler type discovery up a layer #2373

Merged
merged 1 commit into from
May 15, 2024

Conversation

alexcrichton
Copy link
Contributor

This commit lifts the discovery of what type of handler a component is, for example spin-vs-wasi-vs-wasi-snapshot, up one layer from where it currently resides. Previously this determination was made on each request and now it's made when a component first loaded and pre-instantiated instead. This would shift possible errors earlier in the system, for example.

This removes a bit of per-request work and makes the creation of the handler in execute_wasi a bit more straightforward with less guessing of exports for something that was already probed.

@alexcrichton alexcrichton force-pushed the probe-handler-type-once branch from fbb5859 to 4a022e1 Compare March 18, 2024 20:56
crates/core/src/lib.rs Outdated Show resolved Hide resolved
Comment on lines 334 to 371
for (name, _) in ty.exports() {
match name {
WASI_HTTP_EXPORT_2023_10_18 => return Ok(HandlerType::Wasi2023_10_18),
WASI_HTTP_EXPORT_2023_11_10 => return Ok(HandlerType::Wasi2023_11_10),
WASI_HTTP_EXPORT_0_2_0 => return Ok(HandlerType::Wasi0_2),
"fermyon:spin/inbound-http" => return Ok(HandlerType::Spin),
_ => {}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this isn't equivalent to the old code if a component exports more than one of these interfaces. I'm not sure whether that is an issue in practice. @dicej @rylev thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the old code uses the same order, so I think it would behave the same in that (unusual) case.

Copy link
Collaborator

@lann lann Mar 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I'm reading correctly, for an app that exports both spin and wasi interfaces the old code will always return wasi because it checks all exports for wasi first, while the new code will depend on the order of exports() (presumably the order of items in the binary).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's right yeah, I can preserve the exact same behavior as before if desired, but I figured that level of complexity probably wasn't what was intended here

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As long as tooling isn't "likely" to be emitting multiple of these exported interfaces I'm fine with the code as-is. I'm mostly just unsure about spin-componentize.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we're unlikely to run into this situation with components built using Spin provided tooling (e.g., the SDKs). However, it does seem like we'd not want to rely on order of exports to determine which will be invoked, and indeed there should be a preferred ordering of wasi 0.2, wasi release candidates, Spin specific.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've pushed up a commit to generate an error if more than one handler is found to help resolve this

// should probably be removed to just use that instead.
self.linker.substituted_component_type(component)
}

/// Creates a new [`ModuleInstancePre`] for the given [`Module`].
#[instrument(skip_all)]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...though I'm not sure why this one is instrumented either... 🤔

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah it used to acquire a lock I was probably concerned about. Could probably be removed now. 🤷

@alexcrichton alexcrichton force-pushed the probe-handler-type-once branch from bd5bfa8 to d8cf70a Compare March 19, 2024 17:46
@alexcrichton alexcrichton force-pushed the probe-handler-type-once branch from d8cf70a to b2dfbf0 Compare May 14, 2024 22:02
@alexcrichton
Copy link
Contributor Author

I lost this a bit in the shuffle of things, but @lann or others mind if I ask for a re-review on this?

Copy link
Collaborator

@rylev rylev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM just some nits.

Comment on lines 467 to 468
// NB: With Wasmtime 20 and bytecodealliance/wasmtime#8078 this method
// should probably be removed to just use that instead.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we can land #2512 and then remove this?

drop(exports);
Handler::Latest(Proxy::new(&mut store, &instance)?)
}
HandlerType::Spin => unreachable!(),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I prefer using a panic with a message just in case (through some refactoring) this becomes technically reachable.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

panic!("unreachable")

This commit lifts the discovery of what type of handler a component is,
for example spin-vs-wasi-vs-wasi-snapshot, up one layer from where it
currently resides. Previously this determination was made on each
request and now it's made when a component first loaded and
pre-instantiated instead. This would shift possible errors earlier in
the system, for example.

This removes a bit of per-request work and makes the creation of the
handler in `execute_wasi` a bit more straightforward with less guessing
of exports for something that was already probed.

Signed-off-by: Alex Crichton <[email protected]>
@alexcrichton alexcrichton force-pushed the probe-handler-type-once branch from b2dfbf0 to e565b78 Compare May 15, 2024 17:08
@alexcrichton alexcrichton enabled auto-merge May 15, 2024 17:08
@alexcrichton alexcrichton merged commit 5c14552 into fermyon:main May 15, 2024
16 of 17 checks passed
@alexcrichton alexcrichton deleted the probe-handler-type-once branch May 15, 2024 19:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants