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

add option to retain fetchEvent handler #116

Closed

Conversation

karthik2804
Copy link
Contributor

This PR adds the ability to use the fetchEvent Handler provided by StarlingMonkey.

fixes #114

@karthik2804 karthik2804 force-pushed the retain_fetch_event branch 2 times, most recently from ffc32b8 to 2d319cf Compare June 17, 2024 10:31
Copy link
Collaborator

@guybedford guybedford left a comment

Choose a reason for hiding this comment

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

Can we also add this to the readme?

@@ -45,6 +45,7 @@ export async function componentize(jsSource, witWorld, opts) {
worldName,
disableFeatures = [],
enableFeatures = [],
retainFetchEvent = false
Copy link
Collaborator

Choose a reason for hiding this comment

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

I wonder if it would make sense to integrate this into the enableFeatures model and call it fetch-event?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oooh! I like the idea of adding it via the enableFeatures. I will also add it to the readme.

@karthik2804
Copy link
Contributor Author

I think this should wait until we get the fetch PR, so leaving it as a draft.

@@ -130,6 +130,10 @@ Setting `disableFeatures: ['random', 'stdio', 'clocks']` will disable all featur

Note that pure components **will not report errors and will instead trap**, so that this should only be enabled after very careful testing.

The features that are not included by default are:
* `'http'` - Support for sending and receiving HTTP requests, depends on `wasi:io`
* `'fetch-event'` - Enables using `fetchEvent` to respond to `wasi:http/[email protected]#handle`. If the target world does note export `wasi:http/[email protected]`, this will be ignored.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Just like we automatically merge WASI imports into the target world, perhaps we can automatically merge the wasi:http/[email protected] export into the target world when this feature is used?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Actually isn't this the default behaviour anyway? Or do we still strip the export if it's not explicitly in the target world?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

With this PR we want to only optionally strip the export from the StarlingMonkey engine here based on the value of the feature. My intention with that statement is to make it such that, if the target world does not export the interface but the feature is enabled, we should probably still strip the export.

Copy link
Collaborator

@guybedford guybedford Jun 18, 2024

Choose a reason for hiding this comment

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

Shouldn't it read "If the target world does export" though? Rather than "does not". Thinking about this further we probably want to make this an explicit error. That is, if you enable this feature and the target world already exports the incoming handler, then we should throw an error that you should either target the incoming handler export, or you should use the fetch event version of it, but not both.

Copy link
Contributor Author

@karthik2804 karthik2804 Jun 18, 2024

Choose a reason for hiding this comment

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

I think there is a disconnect in what we each mean by the target world. I am talking about the wit definition, not the guest content. As in, consider the following world

package local:hello;

world hello {
  export hello: func(name: string) -> string;
}

and the fetch-event is set, if we do not strip the export from the engine, it will end up in the output component but maybe that is fine?

I also think that there is currently no way to check if a handler is attached to the fetch event but we can check if there is something that targets the incoming handler export so erroring on that would be good, I agree.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Maybe I am misunderstanding here. To verify my understanding - the proposal above is to not retain fetchEvent incase the target world contains the wasi:http/incoming-handler export and only have the feature take effect if it is not explicitly part of the target world.

Copy link
Member

Choose a reason for hiding this comment

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

Oh, I see—I had missed that part of it. On that, I agree with you: I think this setting should be usable whether the targeted world includes incoming-handler or not.

@guybedford doing what you proposed would make it substantially harder to use FetchEvent, because now anyone who wants to target an environment that supports wasi:http/proxy has to edit the target world not to include incoming-handler if they want to use FetchEvent. I think that's a requirement we really shouldn't put on people—and it'd be quite hard for us to satisfy using Spin as a development tool.

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 am happy to update this PR once there is consensus on this discussion.

Copy link
Member

Choose a reason for hiding this comment

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

Guy and I just discussed this further, and came to the realization that there's a cleaner way to do this: with #117, ComponentizeJS will only generate exports for symbols exported at the JS level, too. Based on that, we could simply say "if after treeshaking we still would export the symbol, then we'll do so. Otherwise, we'll leave it alone."

In effect, that'd mean that if the input StarlingMonkey already includes an export, and content doesn't specify that same export, ComponentizeJS will leave the original export alone.

@karthik2804, if that makes sense to you, then changing #117 accordingly should make it so that this issue isn't needed anymore.

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 think I am roughly tracking it. Currently, #117 is purely for imports. I will take a stab at updating it and see if I understand things correctly and report back.

@guybedford
Copy link
Collaborator

Please let me know if I can give any further feedback on this PR, or if you want to arrange a sync to discuss further @karthik2804.

@karthik2804
Copy link
Contributor Author

@guybedford I think this PR can be closed now as #117 enables the use of the fetch event handler as long as the guest content does not export the incomingHandler object.

@karthik2804
Copy link
Contributor Author

Checking back on this - this is not solved by #117 as we decided to remove changes affecting exports. Are we okay to still follow the plan described in #116 (comment) but narrow it down to only the case of wasi-http export? or do we want to go down this route of adding it as a feature as is currently in this PR.

@karthik2804
Copy link
Contributor Author

The above is due to us exiting during the exports_bindgen call here and we do not even get to the point of optionally removing the export here

@tschneidereit
Copy link
Member

I think we should still pursue the plan described in that comment, yes. Based on our conversation just now, that'll require parsing the input .wasm file earlier in the process so we can check whether it has the export in question. That seems okay to me, assuming it's not too challenging to do.

@guybedford
Copy link
Collaborator

I haven't tested the workflows here, but the code path in https://github.com/bytecodealliance/ComponentizeJS/blob/main/crates/spidermonkey-embedding-splicer/src/bindgen.rs#L383 no longer does any skipping at all.

So we are just always leaving the incoming handler export in the final binary, even though it is not reflected in the encoded component.

Therefore it should be possible to simply target a world with the incoming handler to get it handled correctly in the component encoding. It should be possible to test this at the component level by stripping the component encoding and reencoding it with the exported hanlder.

Assuming I've got the above right, then the issue is that we don't use the guest exports to inform whether to use the JS handler or the engine handler when it is present in the world, and instead we will always assume a JS handler thereby overriding the engine one. The way to filter this would be to have an exception for this specific function in that codepath and I'd be fine with that.

@karthik2804
Copy link
Contributor Author

@guybedford I believe you are correct in that the JS handler always overrides the Engine handler. To make sure I understand, are you suggesting that we make an exception just for the HTTP handler specifically with something like before this

if (name == "wasi:http/[email protected]") {
  continue;
}

Alternatively, we could potentially parse the engine earlier and pass in the list of exports it is okay to ignore like @tschneidereit suggests.

I am happy with the first approach as well since that is simpler. Happy to open a new PR once an approach is decided. Thanks!

@guybedford
Copy link
Collaborator

Something like that sounds like it would work to me, yes.

@karthik2804
Copy link
Contributor Author

@guybedford do you have a preference between adding an exception for specific export or making it more general by parsing the engine before we get to the export_bindgen

@guybedford
Copy link
Collaborator

Since this is just for guest exports (since imports always coalesce so there are no conflicts to deal with) and incoming HTTP is the only one currently, hard-coding should be fine.

@guybedford
Copy link
Collaborator

Supported in #122.

@guybedford guybedford closed this Jul 18, 2024
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.

Optionally allow using fetchEvent to handle wasi:http/[email protected]#handle
3 participants