Skip to content

Target environments: local polyfills for environment-specific APIs #3530

@itowlson

Description

@itowlson

(cc @karthik2804, who I believe has been experimenting with something like this)

Consider, wearily, Bob's Discount Cloud. It may be cheap, but it does have one unique feature: a cannon that can fire evildoers into the sun. Applications fire the sun cannon via a bdc:suncannon/fire WIT interface. Bob proudly lists it as an available import in his bdc environment file.

For reasons of vendor neutrality - and, frankly, safety - the Spin CLI does not provide an implementation of bdc:suncannon/fire. Components that import this interface therefore fail to run in the CLI - the components can't even be pre-instantiated - meaning developers can't test sun-cannon based applications before deploying them.

A possible way out of this is to allow environment files to specify polyfills (or stubs or whatever) for imports not available in the CLI. E.g.

# bdc.toml
[polyfill]
"bdc:suncannon/fire@1.0.0" = { url = "https://example.com/sc.wasm", digest = "..." }

When a developer ran a component that imported an interface not available in Spin, but declared and polyfilled in the application's target environment, Spin would compose the polyfill onto the component, in exactly the same way as if the component had declared it as a dependency. This would satisfy the component import. (In practice the way I imagine we'd work this is just to wac everything in the target env's polyfill section onto every component, quietly ignoring cases where the component didn't import the interface. But others probably have a better picture of this than I do.) Karthik describes a better way in his comment below.

The polyfill/stub would have to work within the Spin world. For example, it might print a message to the console, or return a dummy value; in that sense maybe I should call them stubs.

Considerations:

  • What if someone tries to polyfill an interface that Spin already implements? That seems rude but I am not sure how easy it is to detect and disallow it. We can't rely on the namespace because there are wasi: specs we don't implement.
  • What is the permissions model here? E.g. if the polyfill wants to make network requests or access files? Allowing Bob to declare permissions, or even inheritance, in the target env file breaks our usual "only permissions explicitly granted by the developer" model. But we don't want the manifest cluttered with stuff that only exists for the purposes of these laughable fakes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions