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

Component: Unclear how to access exported resource returned by guest #9946

Open
tliron opened this issue Jan 8, 2025 · 4 comments
Open

Component: Unclear how to access exported resource returned by guest #9946

tliron opened this issue Jan 8, 2025 · 4 comments

Comments

@tliron
Copy link

tliron commented Jan 8, 2025

The exported resources example shows how to create a guest resource. Unfortunately it doesn't show how to actually send that resource to an exported client function.

But, to this issue, it doesn't show how to access a resource returned by a call to the guest.

The guest returns ResourceAny, and the documentation does make it clear that this is expected. However, now what?

It cannot be converted to a Resource, because try_into_resource only works on host resources. (That is also not clear in the documentation, I had to delve into the source code to figure that out.)

Also, it's also unclear to me if I must call resource_drop on the value returned by the guest. Or is that necessary just for host resources?

The documentation could be more specific, and the example is not especially useful. In any case, I do not know how to proceed.

@bjorn3
Copy link
Contributor

bjorn3 commented Jan 8, 2025

A resource is an opaque id. I think all the host can do with a guest resource is to pass it as argument when calling a guest function or to call the drop function of the resource.

@tliron
Copy link
Author

tliron commented Jan 8, 2025

@bjorn3 , actually I figured it out and it is possible. The example code is the hint. Here's how it's done:

  1. First, create the dispatcher. From the example: let logger = guest.logger();
  2. Then, do not call call_constructor. We already have the ResourceAny! In fact, call_constructor returns a ResourceAny, too.
  3. So now just call the resource functions via the dispatcher on the ResourceAny that you got from the guest, e.g. logger.call_log(&mut store, my_returned_value, Level::Debug, "hello!")?;
  4. I'm pretty sure you need to drop_resource, too, when you're done. Well, at least it doesn't return an error when I call it.

I wish the example actually showed this. Instead, the example doesn't have any exported functions in the interface, which doesn't seem to me to be a very common scenario.

@alexcrichton
Copy link
Member

@tliron do you have a suggestion for what WIT you'd like to see in the example? it sounds like you figured things out otherwise, but I'd be happy to help update the example to be more useful to you.

@tliron
Copy link
Author

tliron commented Jan 9, 2025

I mostly figured things out, but I'm sorry, I doubt that others would, too.

Also, I'm still not sure if I have to manually resource_drop.

  1. I suggest that the "exported resources example" show a resource being both sent as an argument to an exported function, and also returned from it. So users can see how to create/send a resource and how to deal with one handed to them by the guest.

  2. I think the ResourceAny documentation is confusing and possibly wrong. It says that it can represent either a guest or host resource, but then blends both uses together. It mentions try_from_resource, but that only works on host resources. Generally it is unclear why you would ever need to create a ResourceAny for a host resource in the first place. I mean no disrespect to the author, but I would recommend rewriting that entire section to make it clear why ResourceAny exists for the guest, why it exists for the host, and separate the rules for those two use cases clearly.

On that note, why does wasmtime::component::bindgen emit code that uses ResourceAny, forcing us to unpack and deal with it ourselves? Wouldn't it have been more ergonomic to already handle the conversion to Resource<T> for us? Is there an efficiency concern here?

Again, going back to my suggestion 1, a full example of dealing with this would make these challenges easier to see.

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

No branches or pull requests

3 participants