You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am working on a plugin system for a high performance application using wasmer. Both the host and plugins are written in Rust. WASM allows me to sandbox plugins, have high performance, and have easy (well, not that easy in practice, such as due to this issue) cross-platform dynamic loading. As part of the performance requirements of my use case I need to have a concurrency-first architecture, which means that I need to be able to call plugin code on multiple threads. But, the call function on a Function or TypedFunction requires taking &mut Store, so I can't have shared access to a single Store across my program (even for each plugin) without locking and thus loss of concurrency.
I have considered two solutions to try to resolve this, but neither is ideal.
Firstly, I could create cache only a Module and Imports for each call into the plugins and create a new Instance, as described in #3530. This has some concerns with the Imports being able to access WASM memory as they will sometimes take pointers into said memory as arguments and need to write return values there, so it may not be possible to cache even Imports. Furthermore, it seems like Instance::new is a relatively involved operation as it is linking the full WASM binary to my imports (and potentially WASI imports as well). Although this may be okay for a web server that takes tens of thousands of requests per second, as described in #3530, my use cases requires at least an order of magnitude more calls since the nature of the system is where control flow flows in and out of in addition to between plugins constantly as a matter of course.
Secondly, I could do much the same as previously, but cache the Instance and possibly Imports in a thread local storage with interior mutability. This performance is not ideal since so much duplicated information is held in memory, there's no easy way to clean up this data when a thread exits, and checking is needed every time that a function is called for interior mutability. More concerningly, however, this seems like any global state that a particular plugin holds (i.e., via interiorly mutable statics) would then become thread local as well, which could be a nightmare for plugin developers to debug if they are not expecting it (and I'm sure we all know that developers do not always read as much documentation as they should so simply documenting this is not necessarily enough). I want it to be an easy and frictionless process to write plugins for my system.
Does wasmer have a good way to solve this problem (yet), and have concurrent calls into a WASM module? If not, it would be good to know that too so I do not waste time trying to find one.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
I am working on a plugin system for a high performance application using wasmer. Both the host and plugins are written in Rust. WASM allows me to sandbox plugins, have high performance, and have easy (well, not that easy in practice, such as due to this issue) cross-platform dynamic loading. As part of the performance requirements of my use case I need to have a concurrency-first architecture, which means that I need to be able to call plugin code on multiple threads. But, the call function on a
Function
orTypedFunction
requires taking&mut Store
, so I can't have shared access to a single Store across my program (even for each plugin) without locking and thus loss of concurrency.I have considered two solutions to try to resolve this, but neither is ideal.
Firstly, I could create cache only a
Module
andImports
for each call into the plugins and create a newInstance
, as described in #3530. This has some concerns with theImports
being able to access WASM memory as they will sometimes take pointers into said memory as arguments and need to write return values there, so it may not be possible to cache evenImports
. Furthermore, it seems likeInstance::new
is a relatively involved operation as it is linking the full WASM binary to my imports (and potentially WASI imports as well). Although this may be okay for a web server that takes tens of thousands of requests per second, as described in #3530, my use cases requires at least an order of magnitude more calls since the nature of the system is where control flow flows in and out of in addition to between plugins constantly as a matter of course.Secondly, I could do much the same as previously, but cache the
Instance
and possiblyImports
in a thread local storage with interior mutability. This performance is not ideal since so much duplicated information is held in memory, there's no easy way to clean up this data when a thread exits, and checking is needed every time that a function is called for interior mutability. More concerningly, however, this seems like any global state that a particular plugin holds (i.e., via interiorly mutable statics) would then become thread local as well, which could be a nightmare for plugin developers to debug if they are not expecting it (and I'm sure we all know that developers do not always read as much documentation as they should so simply documenting this is not necessarily enough). I want it to be an easy and frictionless process to write plugins for my system.Does wasmer have a good way to solve this problem (yet), and have concurrent calls into a WASM module? If not, it would be good to know that too so I do not waste time trying to find one.
Beta Was this translation helpful? Give feedback.
All reactions