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

[WIP] Implement wasi-http (requests) for wazero #1519

Closed
wants to merge 3 commits into from

Conversation

brendandburns
Copy link

This is a working pull request, but it's not ready for submission, it is a work in progress to determine where this should land.

It implements the wasi-http specification for HTTP requests from web assembly, but it's pretty hacky just to show what is possible.

I'm sending it now to determine if there is interest in merging this into the repo.

If there is interest, then we can discuss the final structure and I'll clean up the code (a lot)

If there's not interest, I'll find another home for it.

Feedback very welcome, thanks!

@brendandburns
Copy link
Author

I'm attaching a sample http wasm file from https://github.com/dev-wasm/dev-wasm-c/tree/main/http

If you want to try it out, build in this PR, then run

wazero run main.wasm
main.wasm.zip

Copy link
Collaborator

@achille-roussel achille-roussel left a comment

Choose a reason for hiding this comment

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

Hello @brendanburns, thanks a lot for the contribution, we love seeing those kinds of initiatives 🙌

I left a couple of questions on the diff, but besides that I think you're touching on the right point when asking where would be a good place to host this code.

At this time, the wasi-http and streams (which I believe intend to be part of WASI preview 2?) seem to be too experimental to be merged into the main wazero repository. We have been focused on having a robust syscall-like layer based on WASI preview 1, and currently finalizing the addition of non-blocking capabilities to enable a large class of concurrent application to run in Wazero. Because Wazero has reached v1.0, we also commit to the long-term maintenance of the APIs we introduce.

Something you might be interested in as a potential home for this code is https://github.com/stealthrocket/wasi-go. We started that project to have a place to publish those types of experimental wazero host modules, with less concerns about having to introduce breaking changes or portability across languages or operating systems.

Alternatively, this can be hosted in its own repository, and we would be happy to add a link in the Wazero community catalog we maintain at https://github.com/tetratelabs/wazero/blob/main/site/content/community/users.md so that we help users find the code that they are interested in.

Let me know which approach you think would make most sense!

Comment on lines +233 to +240
func Malloc(ctx context.Context, m api.Module, size uint32) (uint32, error) {
malloc := m.ExportedFunction("cabi_realloc")
result, err := malloc.Call(ctx, 0, 0, 4, uint64(size))
if err != nil {
log.Fatalf(err.Error())
}
return uint32(result[0]), err
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is interesting, it seems like a bit of a cyclic dependency: the guest module invokes host module functions but also needs to export the cabi_realloc function that the host can invoke, am I getting that right?

Do you know how widely this has been adopted by compilers? Or whether this API is documented somewhere? (a quick Google search hasn't returned much)

Copy link
Author

Choose a reason for hiding this comment

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

Regarding cabi_realloc it's the way that wasmtime works, there's some discussion here:

bytecodealliance/preview2-prototyping#99

and also some discussion here:

https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md

search for realloc

}
ptr_len := uint32(len(data))
data = append(data, 0)
ptr, err := wasi_http.Malloc(ctx, mod, ptr_len)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is the contract that the allocated memory block will belong to the guest and it will be responsible for freeing it?

Copy link
Author

Choose a reason for hiding this comment

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

There's some discussion of this here:

WebAssembly/wasi-http#7

"github.com/tetratelabs/wazero/imports/wasi_http"
)

var streamsRead = newHostMethod("read", streamReadFn, []api.ValueType{i32, i64, i32}, "a", "b", "c")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is there a mechanism through which the stream can integrate with non-blocking capabilities like wasi_snapshot_preview1.poll_oneoff?

Copy link
Author

@brendandburns brendandburns Jun 14, 2023

Choose a reason for hiding this comment

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

yeah, wasi-http depends on poll in wasi:

https://github.com/WebAssembly/wasi-http/tree/main/wit/deps/poll


// ModuleName is the module name WASI functions are exported into.
//
// See https://github.com/WebAssembly/WASI/blob/snapshot-01/phases/snapshot/docs.md
Copy link
Collaborator

Choose a reason for hiding this comment

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

This link seems misleading, should we point at a place where the default-outgoing-HTTP module is described?

Copy link
Author

Choose a reason for hiding this comment

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

oops, sorry that is a cut/paste left over. I stole a bunch of this code from the wasi implementation :)

@brendandburns
Copy link
Author

@achille-roussel thanks for the quick response. Regarding the wasi-http API it is documented here:

https://github.com/WebAssembly/wasi-http

and has been implemented in the wasmtime runtime from the bytecode alliance (9.0.x)

It's your call whether that is sufficiently stable for wazero though I would argue that it is in the ballpark of stability for wasi.

But I'm happy to pull it out as a separate module. I mainly want this for integration with the dapr project which relies on wazero.

Let me know what you think.

Copy link
Contributor

@codefromthecrypt codefromthecrypt left a comment

Choose a reason for hiding this comment

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

Thanks for getting this started, it is interesting to have an http client impl and seems will continue as things like the server stabilizes.

I concur with @achille-roussel that trying to develop here wouldn't work out well for reasons mentioned. It is also the case generally PRs longer than a week are a bug (we try to keep the queue clean and things close quickly). Something like this would need a lot of work and could distract folks from the daily issues such as waspi1 stuff which is nearly every day still.

Since Achille offered wasi-go, I would take it if I were you ;) You get access to very strong developers who also work on Go. Independent is another route, but basically wasi-go is an alternate CLI so easier to test.

This would help this mature with norms of the wazero ecosystem including tests, benchmarks etc. I can't comment dapr adoption but I think the first thing to do is become stable both in spec and impl and working with wasmtime and also wazero seems a good way towards that, IMHO.

@brendandburns
Copy link
Author

@achille-roussel thanks for the offer to host this in wasi-go, I will refactor this PR to target that repo instead and see what that looks like.

I'll leave this PR open for another day or two in case there is additional discussion, but I'll close it once I open a PR on wasi-go.

@achille-roussel
Copy link
Collaborator

Sounds good!

If you have any questions about wasi-go that are better suited for a short conversation feel free to reach out on the Gopher Slack.

@brendandburns
Copy link
Author

As discussed, closing in favor of dispatchrun/wasi-go#56

achille-roussel pushed a commit to dispatchrun/wasi-go that referenced this pull request Jul 1, 2023
@achille-roussel as discussed in
tetratelabs/wazero#1519 this adds wasi-http
support.

This code is very incomplete and hacky, but it is working for limited
use cases.

If this integration looks correct-ish, I will polish this up, add tests
etc.

Thanks!

---------

Co-authored-by: Brendan Burns <[email protected]>
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