Stream: general

Topic: Managing state and data in Wasm Components


view this post on Zulip Rasmus Øglænd (Mar 04 2025 at 20:07):

Hi everyone,

I'm working on a project with WASM components using the component model, and I could use some guidance on state management within these components. Our goal is to design components that can maintain their own internal state—like updating and reading variables—which might include something as simple as storing and retrieving a string or some numbers. We're using WIT and tools like wit-bindgen to compile our components for the wasm32-wasip2 target, and wanting to run them using Wasmtime.

Here are the main areas where I’m looking for advice:

Basic State Management:
What is the simplest way to maintain state in a WASM component? For example, how can we implement a basic component that exports functions to store and retrieve a simple string value, and then actually run the component in a stateful manner?

Using Resources for State:
I’ve seen many sources suggesting the use of “resources” for state management. Is this the only method available, or are there simpler alternatives? Also, how exactly do resources facilitate state management within a WASM component? Does the state and the data of the resources live inside the wasm components themselves?

Host Involvement with Resources:
Do we need to rely on Wasmtime on the host side to properly manage resources and state? For instance, does the ResourceTable from wasmtime_wasi play a role in this, and if so, how should it be used properly?

Handling Imported Resources in Components:
Consider a scenario where two components each export a resource with its own constructor, and one component imports the other. In this case, the outer component's resource constructor might call the constructor of an imported resource. Is it possible for the outer component to create new instances of the imported resource this way, or must all resources be created and managed by Wasmtime in the host, with resource handles passed explicitly to the components? Additionally, does using tools like wac to connect components—or linking them via the Wasmtime linker/store—handle this automatically? How would we enable this using Wasmtime and the linker/store system?

Running Components with State:
What is the best way to execute these components to ensure that their state behaves as expected?

Our ultimate goal is to have components with private state that remains internal to each WASM component. Even if a component imports exports from another, both should maintain their own independent state. This should hold true even when there are multiple layers of components and imports/exports.

Thanks in advance for any insights or guidance on these issues!

view this post on Zulip Chris Fallin (Mar 04 2025 at 20:12):

When you say "state", can we assume you mean persistent state saved to disk, i.e., between component instantiations? (I am assuming you do not mean state in the literal sense: each module in a component with a heap has the ability to store bytes in that heap, and would be free to implement, say, a key-value store using that heap)

view this post on Zulip Rasmus Øglænd (Mar 04 2025 at 21:09):

To clarify, while persistent storage to disk is a goal for us in the future, our current focus is on properly understanding simple in-memory state management when running components.

For instance, we've noticed that examples using wit-bindgen tend to manage state exclusively via resources, and we haven't seen straightforward cases of components handling simple variables in memory without relying on resources.
Is there a more obvious or simpler method for achieving in-memory state management that we might be overlooking or misunderstanding? If so, we would appreciate specific examples that show how to manipulate values directly in a component's active memory.

And if the use of resources is indeed required, we'd like clarification on that as well as per the previous questions. We welcome guidance on both the persistent storage aspects and the in-memory techniques to ensure we fully grasp how these work within our WASM component model.

view this post on Zulip Chris Fallin (Mar 04 2025 at 22:01):

I'm not the right person to give "official component model advice" but I can say that it's certainly possible to write a component that holds data in-memory and provides an API to access it; it's unclear what constraints you're seeing that prevent that?

The lifetime management aspects are somewhat underspecified here -- perhaps that is part of your question? Longer-lived component holding state being accessed by shorter-lived components that come and go? That "dynamic binding" across lifetimes (i.e., across Wasm stores) is something one would have to build explicit glue for using resource handles or some other mechanism; I don't have any examples to offer unfortunately

view this post on Zulip Lann Martin (Mar 05 2025 at 21:33):

I think you're probably seeing those examples because a lot of us are working on platforms with short-lived instances so there is a bias toward that sort of code. You can definitely keep component instances and their memories around as long as you want.

view this post on Zulip Joel Dice (Mar 05 2025 at 21:51):

Specifically, you can write and read global variables using whatever guest language you happen to be using (e.g. C, Rust, Go, JS, Python, C#, etc.), and the values will persist across an arbitrary number of export calls as long as that component instance exists.

view this post on Zulip Joel Dice (Mar 05 2025 at 21:54):

It's analogous to using a shared library on a traditional platform like Linux or Windows; that library may use global variables to persist state across multiple calls from application code. Components work the same way.

view this post on Zulip Joel Dice (Mar 05 2025 at 21:56):

An exported resource type is another, more object-oriented, way to persist state across calls by giving the caller a handle they can use to refer to a specific piece of state.


Last updated: Apr 07 2025 at 16:03 UTC