-
Notifications
You must be signed in to change notification settings - Fork 13
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
[go] Rework method handling to match latest design #93
Comments
I’ve been thinking about this issue a lot in #82. My current idea is to expose a table interface like wasmtime’s ResourceTable where you can push the underlying data structure for the resource into the table and get an opaque handle (just a UUID in our case) in return that can easily be encoded or decoded. This way, wRPC could operate purely on the level of opaque handles, and the access to underlying user defined resources can be handled by the resource table. Thoughts on this approach? |
Generally, that sounds good to me, I did also think we would need such a construct eventually, but I have two questions though:
|
If it would be helpful, I could try refactoring #82 to use an approach like this! |
A subtle, but very important difference from the wasmtime resource design is that in Wasmtime every function call, be it a freestanding function or a method etc. is received by the (singular) host and any state/data associated with the resource "pointers" is looked up in the table. This works great, because it's the host implementing the resource methods.
Resources' RPC Another way to look at it is that in Wasmtime there's really just two "peers" - the component and the host/the runtime. Let's consider a 3 peer scenario: A, B and C
So how can we make step 3. happen? I generally only see two options here:
The main reason why 2. is chosen in wRPC is to eliminate the hops required to make approach 1. work. With the option 2., the cost of every method call is constant, since it always requires a single roundtrip. Important thing to note that is that even if the resource R could be created during the original (A->B.foo) call, it needs to "escape the scope" and persist even after Of course there's a slightly different approach 3. possible here, which would sort of combine both approaches, where the resource ID is such that it identifies the pair of host/peer and resource itself. E.g. for our example above R could identify some resource X on host A and C could determine that it should call (cc @alexcrichton if you're interested, see the above for the reasoning around the resource design we discussed yesterday) All that said, the design sounds good to me and I'm happy to discuss the details by looking at the implementation. However, given that the |
That does make sense! I also think that integrating the new transport and then working on adding a simplified version of this onto the bindgen is a good approach for now. |
Currently, resources can only be constructed using a constructor in Go bindgen. This effectively makes implementing resources in interfaces not using a constructor (like
wasi:keyvalue
https://github.com/WebAssembly/wasi-keyvalue/blob/219ea3612a53f1bf5b2d137551b22d0268fd3c58/wit/store.wit#L54) impossible, since the implementations should be able to "conjure a resource out of thin air" to support these kind of use cases.It seems that the only way to handle this would be exposing the resource construction and method serving functionality in the generated bindings (or perhaps in
wrpc
module itself?) not tied to the constructorIn current design (implemented, e.g. in Rust), methods, constructors, statics etc. are handled just like regular functions. That should be adopted in Go as well, so instead of assuming there is a unique identifier for each resource and using that in place of "instance", just use the "instance" referring to the method location, just like for any other function
The text was updated successfully, but these errors were encountered: