sen-plugin-host: WASM plugin host runtime for sen-rs
This crate provides the runtime for loading and executing WASM plugins. It enables building plugin-extensible CLI applications with minimal effort.
Architecture
┌─────────────────────────────────────────────────────────────┐
│ Your Application │
├─────────────────────────────────────────────────────────────┤
│ PluginRegistry │
│ ├─ load_plugin("./plugins/hello.wasm") │
│ ├─ execute("hello", &["World"]) │
│ └─ list_commands() │
├─────────────────────────────────────────────────────────────┤
│ HotReloadWatcher (optional) │
│ └─ Watches directories, auto-loads/unloads plugins │
├─────────────────────────────────────────────────────────────┤
│ PluginLoader │
│ ├─ Compiles WASM modules │
│ ├─ Validates API version │
│ └─ Creates sandboxed instances │
├─────────────────────────────────────────────────────────────┤
│ wasmtime (sandboxed execution) │
│ ├─ CPU limits (fuel) │
│ ├─ Stack limits (1MB) │
│ └─ Memory isolation │
└─────────────────────────────────────────────────────────────┘
Features
- Plugin Loading: Load and execute WASM plugins with sandboxed execution
- Hot Reload: Automatically reload plugins when files change
- Plugin Discovery: Scan directories for plugin files
- CPU Limits: Prevent infinite loops with fuel-based execution limits
- Stack Limits: Prevent stack overflow attacks (1MB limit)
sen-integration: Enable integration with sen-rs Router (addsbridgemodule)
Security
Plugins run in a sandboxed WASM environment with multiple protections:
| Protection | Description |
|---|---|
| CPU Limit | 10M instructions per execution (fuel) |
| Stack Limit | 1MB maximum WASM stack |
| Memory Isolation | Each plugin has isolated linear memory |
| No System Access | No filesystem, network, or OS access |
| API Versioning | Rejects plugins with incompatible API versions |
Quick Start
Building Plugins
See the sen-plugin-sdk crate for detailed plugin development guide.
# Add the WASM target (one-time setup)
# Build plugin
Loading and Executing Plugins
Direct Loading
use PluginLoader;
let loader = new?;
let wasm_bytes = read?;
let mut plugin = loader.load?;
// Check plugin metadata
println!;
println!;
// Execute
let result = plugin.instance.execute?;
match result
Using Registry (Recommended)
use PluginRegistry;
let registry = new?;
// Load plugins
registry.load_plugin.await?;
registry.load_plugin.await?;
// List available commands
for cmd in registry.list_commands.await
// Execute by command name
let result = registry.execute.await?;
Hot Reload
Automatically load/reload/unload plugins when files change:
use ;
use Duration;
let registry = new?;
// Watch directory for plugin changes
let _watcher = new.await?;
// Plugins are now automatically managed:
// - New .wasm files are loaded
// - Modified .wasm files are reloaded
// - Deleted .wasm files are unloaded
// Your application continues running...
loop
Plugin Discovery
Scan directories for plugins without hot reload:
use PluginScanner;
let scanner = new?;
let result = scanner.scan_directory?;
println!;
for plugin in &result.plugins
if !result.failures.is_empty
sen-rs Router Integration
Enable the sen-integration feature to integrate plugins with sen-rs Router:
[]
= { = "0.7", = ["sen-integration"] }
use Router;
use ;
let loader = new?;
let plugin = loader.load?;
// Register plugin as a router command
let router = new
.plugin
.with_state;
// Plugin command is now available via the router
let response = router.execute_with.await;
Examples
See examples/wasm-cli/ for a complete example of a plugin-extensible CLI
with hot reload support.