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

sip: component imports #1804

Closed

Conversation

fibonacci1729
Copy link
Contributor

@fibonacci1729 fibonacci1729 commented Sep 25, 2023

source = "other"

[component.other]
source = { path = "bar.wasm" }
Copy link
Collaborator

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?

Copy link
Contributor Author

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?

Copy link
Collaborator

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.

Copy link
Collaborator

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.

Copy link
Collaborator

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.

Copy link
Collaborator

@lann lann Sep 28, 2023

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"]
Copy link
Contributor

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?

docs/content/sips/016-component-imports.md Show resolved Hide resolved
docs/content/sips/016-component-imports.md Outdated Show resolved Hide resolved
docs/content/sips/016-component-imports.md Outdated Show resolved Hide resolved
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"]
Copy link
Contributor

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!

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.

Copy link
Contributor Author

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).

docs/content/sips/016-component-imports.md Show resolved Hide resolved
## 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.
Copy link
Contributor

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?)

Copy link
Collaborator

@rylev rylev Sep 27, 2023

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.

Copy link
Collaborator

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.

docs/content/sips/016-component-imports.md Outdated Show resolved Hide resolved
docs/content/sips/016-component-imports.md Show resolved Hide resolved

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).
Copy link
Contributor

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)?

Copy link
Collaborator

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.

@fibonacci1729 fibonacci1729 force-pushed the component-imports-sip branch 3 times, most recently from 8899444 to 3428324 Compare October 2, 2023 19:52
Signed-off-by: Brian H <[email protected]>
@fibonacci1729
Copy link
Contributor Author

Closing in favor of #2543

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

Successfully merging this pull request may close these issues.

7 participants