-
Notifications
You must be signed in to change notification settings - Fork 259
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
sip: component imports #1804
sip: component imports #1804
Conversation
source = "other" | ||
|
||
[component.other] | ||
source = { path = "bar.wasm" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What would happen if I specified files
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was imagining using wasi-virt; similarly for environment
. I haven't experimented with this just yet so not entirely sure how viable this is.
Do you have any thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we don't go down the route of static composition then each component could have their own instance of wasi.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
each component could have their own instance of wasi.
They can't currently; wasmtime-wasi
(and bindgen in general?) doesn't support linking to anything other than root instances. That is something that could be fixed though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you do dynamic linking, each instance can be backed by a completely separate store so yes it can have different wasi instances. This is how wepl works.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Separate stores would mean we can't use resources, right? (in calls between components)
Imports can be satisfied by associating an import with a component ID which links to a component defined elsewhere in the manifest. | ||
|
||
```toml | ||
[component.foobar.import."foo"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be worth adding an example world with a foo
interface to the SIP to complete the example?
Imports can be satisfied by associating an import with a component ID which links to a component defined elsewhere in the manifest. | ||
|
||
```toml | ||
[component.foobar.import."foo"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would find it really useful for the examples to have more meaningful names than foo
, foobar
and other
!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed. When reading through this foo
, foobar
, and other
might make me confused to fully understand it. That would be great if we had a meaningful name for these terms.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the feedback! I'll update the examples to be a little more intuitive (naming is hard).
## Proposal | ||
|
||
### Changes to Spin Manifest | ||
To support component imports, a new section will be added to the Spin 2.0 manifest design, `[component.<component-id>.import.<import-id>]`. The following sections describe the various options for specifying how to satisfy imports. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this the same as / equivalent to composing components? Or would composition be done as part of build and then import fulfilment is a separate thing that happens at spin up
time?
(If it's not the same as composing components, could we say a bit more about what it is and why users would want it as a distinct thing please?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For simple use cases this could be achieved through static component composition (i.e., taking two components and making them 1 component). However ,there are pros and cons to this approach as opposed to satisfying imports by instantiating the other component and using the instantiated instance in the Host
implementation (what I call "dynamic composition").
Pros of static composition (compared to "dynamic composition")
- It's more performant: there's a penalty paid for exiting the guest and entering the host. Static composition avoids this cost since both components are now the same 1 guest component instead of two separate guest instances.
- It can be shared: static composition creates a single new component that can be shared through a component registry and even run in other environments. Dynamic composition requires a Spin runtime to hook everything up at runtime.
Cons of static composition
- it's less flexible: dynamic composition allows the user to compose components in different ways. As an off the cuff example: imagine a "request sampling" component that we wouldn't to intercept every 10th request to do some sort of sampled metrics but otherwise not touch the other 9 requests. That's not possible with static composition but would be with a host aware dyanmic composition.
I think in general we probably don't want the user to know or care about which approach we take. Exposing composed components that the user can use outside of spin up
should be a separate feature IMO.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Somewhere in-between is "late composition", where an unlocked component is the input to spin up
and gets statically composed at startup.
|
||
This example demonstrates how to use an export name `bar` from `"path/to/component.wasm"` to satisfy component `"foobar"`'s import named `"foo"`. | ||
|
||
> NOTE: The format for each `export` is required to be a kebab-cased name or interface id (e.g. `foo:bar/baz`) as described by the [Component Model Explainer](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#import-and-export-definitions). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the output of resolution e.g. if I have some import sections and do a spin registry push
, what goes into the registry? Is it unfulfilled components with the same import directives, or is it fully linked and self-contained components (guaranteed to be the same as what ran during spin up
)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would depend on what kind of deployment process you have. If you're doing a docker-style "deploy this exact blob" thing then you would probably want to pre-compose as much as possible. If you are pushing into some managed hosting system you might want to let that system do the final composition to allow for automated bug fixes etc in dependencies.
8899444
to
3428324
Compare
Signed-off-by: Brian H <[email protected]>
3428324
to
66eb1b6
Compare
Closing in favor of #2543 |
Rendered