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

Automatically handle semver-compatibility in wasmtime::component::Linker #7860

Closed
alexcrichton opened this issue Feb 2, 2024 · 2 comments · Fixed by #7994
Closed

Automatically handle semver-compatibility in wasmtime::component::Linker #7860

alexcrichton opened this issue Feb 2, 2024 · 2 comments · Fixed by #7994
Labels
wasm-proposal:component-model Issues related to the WebAssembly Component Model proposal wasmtime:api Related to the API of the `wasmtime` crate itself

Comments

@alexcrichton
Copy link
Member

This was discussed this past week at the BA plumbers summit and the conclusion was that part of the WASI release process will be the expectation that runtimes can update WASI and won't need to carry weighty "old" implementation of prior versions of WASI. For example updating from 0.2.1 to 0.2.0 should mean that only one copy of the 0.2.1 WITs are required and only one host implementation is required. Additionally it was concluded that it should be possible to load a module which imports 0.2.0 into a runtime that has updated to 0.2.1, and additionally it should be possible to be forwards compatible as well. Any APIs defined in 0.2.0 but imported at 0.2.1 should still be possible to run on a runtime that only supports 0.2.0. This means, for example, that guest languages can update to 0.2.1 and so long as no new functionality is used from 0.2.1 they'll still run on all 0.2.0 runtimes.

I believe the best way to implement this in Wasmtime will be more fancy logic in the wasmtime::component::Linker type. More-or-less this would involve updating the string used to register imports to chop off the semver-compatible parts. For example foo:bar/baz@0.2.0 would be inserted as foo:bar/baz@0.2. Additionally foo:bar/baz@1.2.0 would become foo:bar/baz@1. That lookup string should be enough for both forwards and backwards compatibility. We'll still be able to rely on normal type-checking as well so this in theory shouldn't cause runtime issues.

This issue is intended to track this implementation change to wasmtime::component::Linker.

@alexcrichton alexcrichton added wasmtime:api Related to the API of the `wasmtime` crate itself wasm-proposal:component-model Issues related to the WebAssembly Component Model proposal labels Feb 2, 2024
@Mossaka
Copy link
Member

Mossaka commented Feb 5, 2024

Thanks for the write up and makes sense to me! I'd like to highlight the crucial aspects of backward and forward compatibility with the WASI 0.2 release:

  1. Backward Compatibility: new runtime supporting 0.2.1 APIs should run components targeting 0.2.0 APIs
  2. Forward Compatibility: old runtime supporting 0.2.0 APIs should run components targeting 0.2.1 APIs

For backward compatibility, it's essential that any modifications to 0.2.1 API signatures or types are implemented in a way that allows the runtime to ignore these changes when executing components targeting 0.2.0.

For forward compatibility, I interpret what you said as as long as the component's using the interfaces / functions / types defined in 0.2.0, they should be able to run on runtimes with 0.2.0 APIs. However, there's no assurance for components targeting newly introduced or altered 0.2.1 APIs.

Is there a plan to introduce a polyfill or similar solution to ensure full forward compatibility when WASI 0.2.1 is released, that is - older runtime can run any components targeting 0.2.1 APIs?

alexcrichton added a commit to alexcrichton/wasmtime that referenced this issue Feb 24, 2024
This commit is an implementation of bytecodealliance#7860 for Wasmtime where
`wasmtime::component::Linker` is now "semver aware". This means that it
assumes that hosts are always managing WIT interfaces in a
semver-aare fashion meaning that semver-compatible upgrade exclusively
adds functionality. This neatly fits into the idea of subtyping at the
instance-level where if a binary built against 0.2.0 only requests a
subset of functionality from a runtime that provides 0.2.1, that should
work just fine.

Specifically what this change does is:

* For all names inserted into a `Linker` there might also be a "semver
  compatible name" which is registered as well. For example `..@1.0.0`
  is also registered as `..@1`.

* Semver-compatible names are only provided for versions without a
  prerelease and with either a nonzero major or minor version number.

* When looking up an item in the linker if no exact match is found then
  if a semver-compatible-name is available for the lookup key then
  that's consulted as well.

This semantically means that if a components imports WASI 0.2.0 then a
runtime which only provides WASI 0.2.1 will be able to instantiate the
component. Furthermore if a component imports WASI 0.2.1 but only
imports the subset of WASI that was available in 0.2.0 then it will be
instantiable in a runtime that only supports 0.2.0.

This implementation is intended to be a crucial part of the evolution to
WASI to make it more seamless to upgrade WASI from both a host and guest
perspective. This no longer requires everyone to upgrade to the same
version all at the same time but instead decouples the upgrade
schedules.

Closes bytecodealliance#7860
@alexcrichton
Copy link
Member Author

Oh dear I apologize @Mossaka I saw your post earlier but only just now saw you had questions at the end:

Is there a plan to introduce a polyfill or similar solution to ensure full forward compatibility when WASI 0.2.1 is released, that is - older runtime can run any components targeting 0.2.1 APIs?

This sort of depends I think. I've posted #7994 now which is an implementation of this issue and, if merged, will ship with Wasmtime 19. That means that Wasmtime 19, which will probably support WASI 0.2.0, will be able to run WASI 0.2.1 when it's released (so long as you don't use any new features). Wasmtime 17 and 18, however, will not have #7994 and won't be able to run WASI 0.2.1 since they have strict version matching.

So on one hand the answer to your question is "yes this is supported", but the other hand is "yes but only if Wasmtime 19+ is used".

Given that I wouldn't expect an "official" polyfill to come into existence, but that's not to say there shouldn't be one of course!

github-merge-queue bot pushed a commit that referenced this issue Feb 27, 2024
This commit is an implementation of #7860 for Wasmtime where
`wasmtime::component::Linker` is now "semver aware". This means that it
assumes that hosts are always managing WIT interfaces in a
semver-aare fashion meaning that semver-compatible upgrade exclusively
adds functionality. This neatly fits into the idea of subtyping at the
instance-level where if a binary built against 0.2.0 only requests a
subset of functionality from a runtime that provides 0.2.1, that should
work just fine.

Specifically what this change does is:

* For all names inserted into a `Linker` there might also be a "semver
  compatible name" which is registered as well. For example `..@1.0.0`
  is also registered as `..@1`.

* Semver-compatible names are only provided for versions without a
  prerelease and with either a nonzero major or minor version number.

* When looking up an item in the linker if no exact match is found then
  if a semver-compatible-name is available for the lookup key then
  that's consulted as well.

This semantically means that if a components imports WASI 0.2.0 then a
runtime which only provides WASI 0.2.1 will be able to instantiate the
component. Furthermore if a component imports WASI 0.2.1 but only
imports the subset of WASI that was available in 0.2.0 then it will be
instantiable in a runtime that only supports 0.2.0.

This implementation is intended to be a crucial part of the evolution to
WASI to make it more seamless to upgrade WASI from both a host and guest
perspective. This no longer requires everyone to upgrade to the same
version all at the same time but instead decouples the upgrade
schedules.

Closes #7860
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wasm-proposal:component-model Issues related to the WebAssembly Component Model proposal wasmtime:api Related to the API of the `wasmtime` crate itself
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants