changed a year ago
Linked with GitHub

WASM integration memo

Expected usecases:

  • Business logic functions (materializer)
    • Incoming requests
    • Event handlers
    • Policy logic
  • Extend platform
    • Integrate off-the-shelf components
    • Allow users to extend runtime
  • Legacy/third-party integration

Materializers

Materializers, in their design, need only take an input and return an output.
When accessing the outside world, they're currently constrained to the typegraph
that hosts them anything external must be mediated through it.

  • Materializers are at a different layer than wherin the component model
    operates.
    • Component model semi-assume a static set of known interfaces that the
      components adhere to.
    • I.e. allowing coarser and foriegn peices of software to interoperate.
    • Materializers are more aking to sections of a single codebase.
  • Typescript works well in this role today and without wasm.
    • Especially assisted with "codegen".

Open questions:

  • A policy for the lifetime of a single materializer instance.
    • Is it recreated for each request? (simpler)
    • Can certain usecases (even handlers) benefit from long-lived instances?
    • Opt in maybe?

Modeling this simple interface for wasm, there are multiple ways this can be
done.

1. Simple

  • Old wasmedge approach.
  • Users write and expose wasm-core functions.
  • Host functionality is exposed through libraries that wrap the wasm-core
    bindings.
    • Libraries will need to be published for each guest language.

2. Component + Typegraph derived WIT world (wit_gen)

  • Generate a WIT idl based on the typegraph.
    • Contains types from the typegraph.
    • Will refer to published WIT for common host functionality.
    • interface exposed {} (stretch)
      • World can import exposed to access wrapper functions for typegraph
        exposed materializers.
      • Eliminates need gql crutch.
  • Users will author components that adheres to this spec.
    • Code-generation falls on the WIT tooling of the language.
    • User experience will vary depending on chosen guest launguage.
  • Typegate will need to dynamically model and interact with the generated WIT.
    • Most tooling today assumes static, compile time WIT but it is doable.

3. Component + Wire (wit_wire)

  • Guests expose a single handle function that takes and returns JSON strings.
    • Function will implement command pattern, commonly to respond to incoming
      requests.
    • Typegate will (de)serialize and validate the type shapes on both side.
    • JSON is universally supported.
  • Host will expose a single hostcall function.
    • Implements JSON based command object pattern as well.
    • Access to the typegraph exposed mats will take form of GraphQl queries.
  • Use code generation to hide command action pattern.
    • Users will only be exposed:
      • types described in the typegraph
      • stubs they implment for their materializers.
    • Codegen will do the actual json command action pattern.
    • Gql object (partially typed
      Image Not Showing Possible Reasons
      • The image file may be corrupted
      • The server hosting the image is unavailable
      • The image path is incorrect
      • The image format is not supported
      Learn More →
      ) can function similarly.

Although, on paper, the wire protocol can be built upon wasm-core functions,
using WASI here would be advantageous since:

  • When WASI 0.3 lands, it should allow easy async interop.
  • Canonical ABI means we can minimize JSON usage.
  • Allows for adaptors components that comsume wasi based components.

VM based languages

VM based languages provide some challenges but also the opportunity to bridge
the gap with the golden standard of the Deno runtime. Since they'll ultimately
be used to implement materializers, their impl ought to be able to utilize the
wit_wire interface. SDK generators like include_lambda can be supported through
the init-args parameter.

4. Wasm core + Wire (core_wire)

This is similar to wit_wire but relies only on wasm core. Can be a used to add langauges that don't support components yet.

Platform extension

Runtimes in their implementation today have a semi-standard interfaces.
Authoring a WIT world to model Runtimes seems pretty straight forward and would
end up using standard component model elements.

Now, as to what the usecases here are and on the question of how you'd make it
easy to extend the sdk, this document does not bite.

Legacy integration

Compiling an already existing codebase to WASM is one avenue for legacy
integration. A rough sketch of that would be like:

  • Use importers to generate typegraph types for the legacy codebase interface.
  • A special runtime that exposes works with wasi:http/incoming-handler.
  • Makes use of standard wasi component model elements.
Select a repo