sausage core: modules per topic, journal writer thread with WAL and batches, hash cache by metadata, 49 tests per rule
Blank stdout lines give no warning. core.exit requests the exit in its own handler.
This commit is contained in:
+25
-3
@@ -20,6 +20,7 @@ use wasmtime_wasi::p2::bindings::Command;
|
||||
use wasmtime_wasi::{FsPerms, I32Exit, WasiCtx, WasiCtxView, WasiView};
|
||||
use wasmtime_wasi_http::{WasiHttpCtx, WasiHttpCtxView, WasiHttpHooks, WasiHttpView};
|
||||
|
||||
/// The HTTP transport hooks supplied to WASI processes.
|
||||
pub struct HttpHooks {
|
||||
allow: bool,
|
||||
}
|
||||
@@ -54,6 +55,7 @@ impl WasiHttpHooks for HttpHooks {
|
||||
}
|
||||
}
|
||||
|
||||
/// The WASI and HTTP resources owned by one store.
|
||||
pub struct ProcessState {
|
||||
ctx: WasiCtx,
|
||||
table: ResourceTable,
|
||||
@@ -80,6 +82,7 @@ impl WasiHttpView for ProcessState {
|
||||
}
|
||||
}
|
||||
|
||||
/// A Wasmtime engine and linker shared by the world.
|
||||
pub struct Runtime {
|
||||
engine: Engine,
|
||||
linker: Linker<ProcessState>,
|
||||
@@ -106,18 +109,23 @@ impl std::fmt::Display for Exit {
|
||||
}
|
||||
}
|
||||
|
||||
/// The filesystem, network, and environment supplied to one process.
|
||||
pub struct InstanceConfig {
|
||||
/// The world folder to preopen as the guest root.
|
||||
pub world: PathBuf,
|
||||
/// Outgoing HTTP, and TCP, UDP, and DNS through `wasi:sockets`.
|
||||
pub network: bool,
|
||||
/// The environment variables supplied to the guest.
|
||||
pub env: Vec<(String, String)>,
|
||||
}
|
||||
|
||||
/// A running guest. Dropping it kills the guest.
|
||||
pub struct Instance {
|
||||
/// The host end of stdin, removed when the process stops.
|
||||
pub stdin: Option<DuplexStream>,
|
||||
/// Lines that the guest writes to stdout. Closed when the guest ends.
|
||||
pub stdout: mpsc::Receiver<String>,
|
||||
/// The stderr lines that the process writes.
|
||||
pub stderr: mpsc::Receiver<String>,
|
||||
task: JoinHandle<Exit>,
|
||||
}
|
||||
@@ -178,6 +186,7 @@ fn short_trap(full: &str) -> String {
|
||||
}
|
||||
|
||||
impl Runtime {
|
||||
/// Create an engine with disk caching and a ten-millisecond epoch tick.
|
||||
pub fn new(cache: &Path) -> Result<Arc<Self>> {
|
||||
let mut config = Config::new();
|
||||
config.epoch_interruption(true);
|
||||
@@ -206,11 +215,17 @@ impl Runtime {
|
||||
Ok(runtime)
|
||||
}
|
||||
|
||||
/// Compile component bytes through Wasmtime's disk cache.
|
||||
pub fn compile(&self, bytes: &[u8]) -> Result<Component> {
|
||||
Ok(Component::new(&self.engine, bytes)?)
|
||||
}
|
||||
|
||||
pub fn start(self: &Arc<Self>, component: &Component, cfg: InstanceConfig) -> Result<Instance> {
|
||||
/// Prepare a world preopen off the async workers, then start the WASI task.
|
||||
pub async fn start(
|
||||
self: &Arc<Self>,
|
||||
component: &Component,
|
||||
cfg: InstanceConfig,
|
||||
) -> Result<Instance> {
|
||||
let (host_in, guest_in) = tokio::io::duplex(64 * 1024);
|
||||
let (guest_out, host_out) = tokio::io::duplex(64 * 1024);
|
||||
|
||||
@@ -229,7 +244,12 @@ impl Runtime {
|
||||
b.env(k, v);
|
||||
}
|
||||
// Filesystem setup lives here. T6 replaces this preopen with the VFS.
|
||||
b.preopened_dir(&cfg.world, "/", FsPerms::ReadWrite)?;
|
||||
let world = cfg.world;
|
||||
let mut b = tokio::task::spawn_blocking(move || -> Result<_> {
|
||||
b.preopened_dir(world, "/", FsPerms::ReadWrite)?;
|
||||
Ok(b)
|
||||
})
|
||||
.await??;
|
||||
let state = ProcessState {
|
||||
ctx: b.build(),
|
||||
table: ResourceTable::new(),
|
||||
@@ -245,7 +265,9 @@ impl Runtime {
|
||||
if n == 0 {
|
||||
break;
|
||||
}
|
||||
let line = String::from_utf8(std::mem::take(&mut bytes)).unwrap_or_default();
|
||||
// Preserve a non-blank invalid line so routing emits its warning.
|
||||
let line = String::from_utf8(std::mem::take(&mut bytes))
|
||||
.unwrap_or_else(|_| "\u{fffd}".into());
|
||||
if line_tx.send(line).await.is_err() {
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user