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

[water-api] new API design draft #2

Merged
merged 17 commits into from
Oct 7, 2023
Merged

[water-api] new API design draft #2

merged 17 commits into from
Oct 7, 2023

Conversation

gaukas
Copy link
Contributor

@gaukas gaukas commented Sep 22, 2023

Note: Corresponding sample .wasm file, tests, documentations and README still pending.

  • Redesign RuntimeConn into an interface{}/net.Conn, support future multi-versioning.
  • Split wasm runtime into runtimeCore for modularization.
  • Pass WAConfig into WASM.
  • Implement RuntimeListener to directly listen on a local TCP port or Unix address

@gaukas gaukas self-assigned this Sep 22, 2023
@gaukas
Copy link
Contributor Author

gaukas commented Sep 22, 2023

For code-review purposes, you might want to start from Dial() in runtime_conn_dialer.go.

core.go Outdated

// get version
// In a _version() call, the WASM module will return its version
ret, err := c._version.Call(c.store)
Copy link
Member

Choose a reason for hiding this comment

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

Not too sure how Go handles function with no return, but I forgot to add a check for it if there is no return value for the _version function in Rust previously.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If the function returns successfully, then the interface{} return argument will be the result of the function. If there were 0 results then this value is nil. If there was one result then this is that result. Otherwise if there were multiple results then []Val is returned.

From func (*Func) Call()'s definition.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But let's forget about the multi-value for V0 (version in terms of of water API). It is not FFI-friendly and we don't take risks.

Copy link
Member

Choose a reason for hiding this comment

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

It's way neater in Go, not like Rust, you need to pass in a &mut [Val] with the exact length of the return values, otherwise it will fail the call.

Copy link
Contributor Author

@gaukas gaukas Sep 23, 2023

Choose a reason for hiding this comment

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

fail the call

What's the behavior then? Returning some bad values, an error (a trap), or panic the entire host program (that's the worst)?

Copy link
Member

@erikziyunchi erikziyunchi Sep 23, 2023

Choose a reason for hiding this comment

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

Yeah, it will panic the the entire host 🫠, it's returning a Result<Err(E)> if I do .unwrap() or ? then it will panic the host where it's actually avoidable by adding some handling code for that case. But currently I'm passing something like this to the call to avoid it.

let mut res = vec![Val::I32(0); version_fn.ty(&self.store).results().len()];

}

// push WAConfig
configFd, err := rcv.core.store.PushFile(rcv.core.config.WAConfig.File(), wasmtime.READ_ONLY)
Copy link
Member

Choose a reason for hiding this comment

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

It might be better to ask WASM for the fd? Since it might cause conflict when there are many files that is open in WASM but closed in Host + many fd's for network streams. The way I was doing is fix config file's fd to be always 3 since in the pipeline, and we can have a global_available_fd in WASM to keep track on the next available fd, so there won't be any conflict.

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 thought that's what PushFile does:

PushFile keeps track of next unused fd in WasiCtx and binding the file to it. That's what makes it different from InsertFile.

Am I getting it wrong or something?

Copy link
Member

Choose a reason for hiding this comment

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

My bad, I forgot that you were using PushFile, I should too!

Now example is working.
File descriptors will not work on Windows anyways...
@gaukas gaukas requested a review from erikziyunchi September 29, 2023 06:18
@gaukas gaukas merged commit 07165d1 into master Oct 7, 2023
4 checks passed
@gaukas gaukas deleted the dev branch October 7, 2023 02:57
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.

2 participants