-
Notifications
You must be signed in to change notification settings - Fork 259
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
Conversation
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
|
There was a problem hiding this 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!
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 | ||
} |
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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:
"github.com/tetratelabs/wazero/imports/wasi_http" | ||
) | ||
|
||
var streamsRead = newHostMethod("read", streamReadFn, []api.ValueType{i32, i64, i32}, "a", "b", "c") |
There was a problem hiding this comment.
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
?
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 :)
@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 It's your call whether that is sufficiently stable for 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. |
There was a problem hiding this 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.
@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. |
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. |
As discussed, closing in favor of dispatchrun/wasi-go#56 |
@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]>
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!