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

PROP - 42 - Add External Wasm Runtime #46

Open
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

rodneyosodo
Copy link
Member

@rodneyosodo rodneyosodo commented Jan 8, 2025

What type of PR is this?

This is a feature because it adds two new examples: a long-running computation example and a "hello world" example. It also modifies the proplet runtime to accept command-line arguments and use an external WASM runtime if specified.

What does this do?

This pull request introduces several enhancements to the project's infrastructure and functionality. The changes span multiple files, including updates to the Makefile, configuration management, example programs, and runtime execution. The modifications extend the build process, add new example applications, introduce command-line argument handling for WebAssembly runtime, and provide more flexible task result management. The updates aim to improve the project's configurability and expand its example ecosystem.

Which issue(s) does this PR fix/relate to?

Have you included tests for your changes?

Tested manually

Did you document any new/modified features?

Notes

sequenceDiagram
    participant C as Client
    participant R as wazeroRuntime
    participant E as wazero
    participant P as PubSub

    C->>R: StartApp(wasmBinary, cliArgs, id)
    alt hostWasmRuntime is not set i.e runs on embedded runtime
        R->>E: Execute WASM
        activate E
        Note over E: Process runs
        E-->>R: Capture results
        deactivate E
        R->>P: Publish results
    end
Loading
sequenceDiagram
    participant C as Client
    participant R as hostRuntime
    participant F as Filesystem
    participant E as External Runtime
    participant P as PubSub

    C->>R: StartApp(wasmBinary, cliArgs, id)
    alt hostRuntime is set
        R->>F: Create temporary WASM file
        R->>F: Write wasmBinary to file
        R->>E: Execute WASM with cliArgs
        activate E
        Note over E: Process runs
        E-->>R: Capture stdout
        deactivate E
        R->>P: Publish results
        R->>F: Remove temporary file
    end
Loading
sequenceDiagram
    participant Client
    participant PropletService
    participant Runtime
    participant HostRuntime

    Client->>PropletService: Start WebAssembly App
    PropletService->>Runtime: StartApp(wasmBinary, cliArgs)
    alt Host Runtime Specified
        Runtime->>HostRuntime: Execute WebAssembly
        HostRuntime-->>Runtime: Return Execution Results
    else Default Runtime
        Runtime->>Runtime: Execute WebAssembly Directly
    end
    Runtime-->>PropletService: Return Execution Status
    PropletService-->>Client: Confirm Application Start
Loading

@drasko
Copy link
Contributor

drasko commented Jan 9, 2025

I do not get on the diagram - why do you need Wazero? Isn't it enough that Proplet just kicks Wasmtime subprocess, giving it Wasm file as a entry parameter?

proplet/wasm.go Outdated
}

func NewWazeroRuntime(logger *slog.Logger, pubsub mqtt.PubSub, channelID string) Runtime {
func NewWazeroRuntime(logger *slog.Logger, pubsub mqtt.PubSub, channelID, hostWasmRuntime string) Runtime {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hostRuntime should not be a part of this structure, it has nothing to do with Wazero.

Maybe change this to NewWasmRuntime, and then return either Wazero or external, but this does not make sense.

proplet/wasm.go Outdated
}
}

func (w *wazeroRuntime) StartApp(ctx context.Context, wasmBinary []byte, id, functionName string, args ...uint64) error {
func (w *wazeroRuntime) StartApp(ctx context.Context, wasmBinary []byte, cliArgs []string, id, functionName string, args ...uint64) error {
if w.hostWasmRuntime != "" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be OK, but rather declare interface WasmRuntime, and then implement different StartApp functions for different runtimes (Wazero or Wasmtime or whatever)

Add two examples:
- one example is a process that takes long to compute
- the other one is a hello world example that prints out the response to stdout

service, err := proplet.NewService(ctx, cfg.ChannelID, cfg.ThingID, cfg.ThingKey, cfg.LivelinessInterval, mqttPubSub, logger, wazero)
runtime := runtimes.NewWazeroRuntime(logger, mqttPubSub, cfg.ChannelID)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer doing it with if-else, then re-assigning and calling New two times in the worst case. It documents better the intention.

switch cfg.ExternalWasmRuntime != "" {
case true:
runtime = runtimes.NewHostRuntime(logger, mqttPubSub, cfg.ChannelID, cfg.ExternalWasmRuntime)
case false:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use default here, as a catch-all

Copy link
Contributor

@drasko drasko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

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.

Feature: Enable Optional External Wasm Runtime
2 participants