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

Store per-instance data? #2491

Closed
chifflier opened this issue Dec 9, 2020 · 5 comments
Closed

Store per-instance data? #2491

chifflier opened this issue Dec 9, 2020 · 5 comments

Comments

@chifflier
Copy link

Hi,
Is there a way to store data in instance?
I have a situation where guest calls a host function get_info_xxx, and host needs to identify which instance is asking to send the correct data.
I tried looking at examples and doc and could not find the solution. Best I can think of is storing data or an identifier by capturing it in the environment of Func when creating the Instance, however this is not convenient, since the data is evolving over time (and not known when creating the instance).
So, at the moment I'm considering having a global structure to store per-instance data, and give an identifier to instances (captured in callbacks). This may work, but require lots of code (global variables and unsafe access, need for a lock, etc.) that could be avoided if host could just update per-instance data before calling.

Is there a better way of having (dynamic) per-instance data?
Thanks!

@alexcrichton
Copy link
Member

Currently you cannot attach data to an Instance or a wasm_instance_t. Can you clarify whether you're using the C or the Rust API? The current intention is that any instance-specific data can live in the Func items you hook up into an instance, but we can of course always add other storage mechanisms too!

@chifflier
Copy link
Author

Oh, forgot to mention that. I'm using the Rust API

In most cases, closures are a good way to have per-instance data. But my data will change before every call: the application uses WASM for out of browser plugins, so the application processes data, then call WASM function for each plugin. There is also contextual data, that would be too costly to copy to guest before every call, so the intent is to provide it "on-demand" when the guest requests it.
I was thinking that maybe storing data in the instance and make it available in Caller would be a solution (wasmer has a data member in the Ctx structure, for example), but I am not familiar with available APIs, and wanted to make sure I am not missing something obvious.

I'm still experimenting: I tested a solution with a global RwLock<HashMap<...>> which works but adds lots of locking code everywhere. Maybe something simpler is to create an Arc<Mutex<...>> before creating the imports, and capture it in the closure in Func?

@alexcrichton
Copy link
Member

Unfortunately Caller isn't a great solution here I think. That's sort of a hack around the lack of interface types today, but in general it's very limiting from a wasm-semantics point of view to place restrictions on who and what can call a function (e.g. that your import would only work when called from the wasm module specifically).

I'm not familiar enough with your use case but I suspect a combination of Rc and RefCell would be able to help too?

@chifflier
Copy link
Author

It works! I tested two solutions, one based on Arc<Mutex<T>> and one on Rc<RefCell<T>>. Basically, the application main loop keeps a reference and updates data, while each closure also have a reference and can access data. The choice between the two depends on the application using threads, as usual.

Thanks @alexcrichton for your help, and the explanations.

@alexcrichton
Copy link
Member

Ok great, glad it worked out!

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

2 participants