feat: add wasmtime host with epoch-bounded WasmProvider
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Generated
+349
-5
@@ -26,6 +26,21 @@ version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
||||
|
||||
[[package]]
|
||||
name = "ambient-authority"
|
||||
version = "0.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e9d4ee0d472d1cd2e28c97dfa124b3d8d992e10eb0a035f33f5d12e3a177ba3b"
|
||||
|
||||
[[package]]
|
||||
name = "android_system_properties"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.102"
|
||||
@@ -176,6 +191,74 @@ version = "1.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
|
||||
|
||||
[[package]]
|
||||
name = "cap-fs-ext"
|
||||
version = "3.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5528f85b1e134ae811704e41ef80930f56e795923f866813255bc342cc20654"
|
||||
dependencies = [
|
||||
"cap-primitives",
|
||||
"cap-std",
|
||||
"io-lifetimes",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cap-net-ext"
|
||||
version = "3.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20a158160765c6a7d0d8c072a53d772e4cb243f38b04bfcf6b4939cfbe7482e7"
|
||||
dependencies = [
|
||||
"cap-primitives",
|
||||
"cap-std",
|
||||
"rustix",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cap-primitives"
|
||||
version = "3.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6cf3aea8a5081171859ef57bc1606b1df6999df4f1110f8eef68b30098d1d3a"
|
||||
dependencies = [
|
||||
"ambient-authority",
|
||||
"fs-set-times",
|
||||
"io-extras",
|
||||
"io-lifetimes",
|
||||
"ipnet",
|
||||
"maybe-owned",
|
||||
"rustix",
|
||||
"rustix-linux-procfs",
|
||||
"windows-sys 0.52.0",
|
||||
"winx",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cap-std"
|
||||
version = "3.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6dc3090992a735d23219de5c204927163d922f42f575a0189b005c62d37549a"
|
||||
dependencies = [
|
||||
"cap-primitives",
|
||||
"io-extras",
|
||||
"io-lifetimes",
|
||||
"rustix",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cap-time-ext"
|
||||
version = "3.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "def102506ce40c11710a9b16e614af0cde8e76ae51b1f48c04b8d79f4b671a80"
|
||||
dependencies = [
|
||||
"ambient-authority",
|
||||
"cap-primitives",
|
||||
"iana-time-zone",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"winx",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.63"
|
||||
@@ -200,6 +283,17 @@ version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
||||
|
||||
[[package]]
|
||||
name = "chacha20"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures 0.3.0",
|
||||
"rand_core 0.10.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cmake"
|
||||
version = "0.1.58"
|
||||
@@ -292,6 +386,15 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-assembler-x64"
|
||||
version = "0.132.0"
|
||||
@@ -659,6 +762,17 @@ dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fs-set-times"
|
||||
version = "0.20.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94e7099f6313ecacbe1256e8ff9d617b75d1bcb16a6fddef94866d225a01a14a"
|
||||
dependencies = [
|
||||
"io-lifetimes",
|
||||
"rustix",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fs_extra"
|
||||
version = "1.3.0"
|
||||
@@ -813,6 +927,7 @@ dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"r-efi 6.0.0",
|
||||
"rand_core 0.10.1",
|
||||
"wasip2",
|
||||
"wasip3",
|
||||
]
|
||||
@@ -987,6 +1102,30 @@ dependencies = [
|
||||
"windows-registry",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.65"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470"
|
||||
dependencies = [
|
||||
"android_system_properties",
|
||||
"core-foundation-sys",
|
||||
"iana-time-zone-haiku",
|
||||
"js-sys",
|
||||
"log",
|
||||
"wasm-bindgen",
|
||||
"windows-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone-haiku"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_collections"
|
||||
version = "2.2.0"
|
||||
@@ -1121,6 +1260,22 @@ dependencies = [
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "io-extras"
|
||||
version = "0.18.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2285ddfe3054097ef4b2fe909ef8c3bcd1ea52a8f0d274416caebeef39f04a65"
|
||||
dependencies = [
|
||||
"io-lifetimes",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "io-lifetimes"
|
||||
version = "2.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06432fb54d3be7964ecd3649233cddf80db2832f47fec34c01f65b3d9d774983"
|
||||
|
||||
[[package]]
|
||||
name = "ipnet"
|
||||
version = "2.12.0"
|
||||
@@ -1233,6 +1388,12 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "leb128"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6cc46bac87ef8093eed6f272babb833b6443374399985ac8ed28471ee0918545"
|
||||
|
||||
[[package]]
|
||||
name = "leb128fmt"
|
||||
version = "0.1.0"
|
||||
@@ -1319,6 +1480,12 @@ version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3"
|
||||
|
||||
[[package]]
|
||||
name = "maybe-owned"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4facc753ae494aeb6e3c22f839b158aebd4f9270f55cd3c79906c45476c47ab4"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.8.1"
|
||||
@@ -1560,7 +1727,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"getrandom 0.3.4",
|
||||
"lru-slab",
|
||||
"rand",
|
||||
"rand 0.9.4",
|
||||
"ring",
|
||||
"rustc-hash",
|
||||
"rustls",
|
||||
@@ -1614,7 +1781,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea"
|
||||
dependencies = [
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
"rand_core 0.9.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207"
|
||||
dependencies = [
|
||||
"chacha20",
|
||||
"getrandom 0.4.2",
|
||||
"rand_core 0.10.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1624,7 +1802,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
"rand_core 0.9.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1636,6 +1814,12 @@ dependencies = [
|
||||
"getrandom 0.3.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69"
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.12.0"
|
||||
@@ -1805,6 +1989,16 @@ dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix-linux-procfs"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fc84bf7e9aa16c4f2c758f27412dc9841341e16aa682d9c7ac308fe3ee12056"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"rustix",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.23.40"
|
||||
@@ -2031,7 +2225,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"cpufeatures 0.2.17",
|
||||
"digest",
|
||||
]
|
||||
|
||||
@@ -2995,6 +3189,58 @@ dependencies = [
|
||||
"wit-parser 0.248.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmtime-wasi"
|
||||
version = "45.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb1e92a304eaafd672718011c69084041db74fa0fcc3532c5920f492c557b721"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bitflags",
|
||||
"bytes",
|
||||
"cap-fs-ext",
|
||||
"cap-net-ext",
|
||||
"cap-std",
|
||||
"cap-time-ext",
|
||||
"cfg-if",
|
||||
"fs-set-times",
|
||||
"futures",
|
||||
"io-extras",
|
||||
"io-lifetimes",
|
||||
"rand 0.10.1",
|
||||
"rustix",
|
||||
"thiserror 2.0.18",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"url",
|
||||
"wasmtime",
|
||||
"wasmtime-wasi-io",
|
||||
"wiggle",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmtime-wasi-io"
|
||||
version = "45.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e0013e1f37d2e0e1b030fa186972f6f5819f69814bb07d3b6d3cab0c40b50e2"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
"futures",
|
||||
"tracing",
|
||||
"wasmtime",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wast"
|
||||
version = "35.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2ef140f1b49946586078353a453a1d28ba90adfc54dde75710bc1931de204d68"
|
||||
dependencies = [
|
||||
"leb128",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wast"
|
||||
version = "251.0.0"
|
||||
@@ -3014,7 +3260,7 @@ version = "1.251.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81b1086c9e85b95bd6a229a928bc6c6d0662e42af0250c88d067b418831ea4d4"
|
||||
dependencies = [
|
||||
"wast",
|
||||
"wast 251.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3074,6 +3320,47 @@ dependencies = [
|
||||
"tower",
|
||||
"tracing",
|
||||
"wasmtime",
|
||||
"wasmtime-wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wiggle"
|
||||
version = "45.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7c048e5d47058ff8b60cef771dd6276f2cf4508bc7f604b93c8d5d643ad41fc"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"thiserror 2.0.18",
|
||||
"tracing",
|
||||
"wasmtime",
|
||||
"wasmtime-environ",
|
||||
"wiggle-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wiggle-generate"
|
||||
version = "45.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b867ae624c2006976985444321d429ee2d0c6784ca5c6e45bc140c48141bb0c"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasmtime-environ",
|
||||
"witx",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wiggle-macro"
|
||||
version = "45.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "463d6d4c0c100180fdfc586d555ed1c22376114944841629cff0d746666e30a4"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wiggle-generate",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3126,6 +3413,41 @@ dependencies = [
|
||||
"wasmtime-internal-cranelift",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.62.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
|
||||
dependencies = [
|
||||
"windows-implement",
|
||||
"windows-interface",
|
||||
"windows-link",
|
||||
"windows-result",
|
||||
"windows-strings",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-implement"
|
||||
version = "0.60.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-interface"
|
||||
version = "0.59.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.2.1"
|
||||
@@ -3329,6 +3651,16 @@ version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1"
|
||||
|
||||
[[package]]
|
||||
name = "winx"
|
||||
version = "0.36.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f3fd376f71958b862e7afb20cfe5a22830e1963462f3a17f49d82a6c1d1f42d"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen"
|
||||
version = "0.51.0"
|
||||
@@ -3527,6 +3859,18 @@ dependencies = [
|
||||
"wasmparser 0.248.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "witx"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e366f27a5cabcddb2706a78296a40b8fcc451e1a6aba2fc1d94b4a01bdaaef4b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"log",
|
||||
"thiserror 1.0.69",
|
||||
"wast 35.0.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "writeable"
|
||||
version = "0.6.3"
|
||||
|
||||
@@ -16,6 +16,7 @@ thiserror = "2"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
tracing = "0.1"
|
||||
wasmtime = { version = "45", features = ["component-model"] }
|
||||
wasmtime-wasi = "45"
|
||||
|
||||
[dev-dependencies]
|
||||
http-body-util = "0.1"
|
||||
|
||||
@@ -3,3 +3,4 @@ pub mod fetch;
|
||||
pub mod http;
|
||||
pub mod model;
|
||||
pub mod service;
|
||||
pub mod wasm;
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
use std::path::Path;
|
||||
|
||||
use wasmtime::component::{Component, Linker};
|
||||
use wasmtime::{Config, Engine, Store};
|
||||
use wasmtime_wasi::{ResourceTable, WasiCtx, WasiCtxBuilder, WasiCtxView, WasiView};
|
||||
|
||||
use crate::error::HostError;
|
||||
use crate::model::{Comment, Entry, FetchedResponse, ParseOutcome};
|
||||
use crate::service::ProviderHandle;
|
||||
|
||||
wasmtime::component::bindgen!({
|
||||
world: "provider",
|
||||
path: "../../wit",
|
||||
});
|
||||
|
||||
use exports::whoareyou::provider::lookup::{
|
||||
LookupError as WitLookupError, Response as WitResponse,
|
||||
};
|
||||
|
||||
/// How many epoch ticks a guest call may run. The epoch thread ticks every
|
||||
/// 100 ms → 50 ticks ≈ 5 s budget per call.
|
||||
const EPOCH_DEADLINE_TICKS: u64 = 50;
|
||||
pub const EPOCH_TICK: std::time::Duration = std::time::Duration::from_millis(100);
|
||||
|
||||
pub struct HostState {
|
||||
ctx: WasiCtx,
|
||||
table: ResourceTable,
|
||||
}
|
||||
|
||||
impl WasiView for HostState {
|
||||
fn ctx(&mut self) -> WasiCtxView<'_> {
|
||||
WasiCtxView {
|
||||
ctx: &mut self.ctx,
|
||||
table: &mut self.table,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn engine() -> Result<Engine, HostError> {
|
||||
let mut config = Config::new();
|
||||
|
||||
config.epoch_interruption(true);
|
||||
|
||||
Ok(Engine::new(&config)?)
|
||||
}
|
||||
|
||||
pub fn linker(engine: &Engine) -> Result<Linker<HostState>, HostError> {
|
||||
let mut linker = Linker::new(engine);
|
||||
|
||||
wasmtime_wasi::p2::add_to_linker_sync(&mut linker)?;
|
||||
|
||||
Ok(linker)
|
||||
}
|
||||
|
||||
/// Spawn the thread that advances the engine epoch so runaway guest calls
|
||||
/// trap instead of hanging the service. Call once at startup.
|
||||
pub fn spawn_epoch_thread(engine: &Engine) {
|
||||
let engine = engine.clone();
|
||||
|
||||
std::thread::spawn(move || {
|
||||
loop {
|
||||
std::thread::sleep(EPOCH_TICK);
|
||||
engine.increment_epoch();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub struct WasmProvider {
|
||||
name: String,
|
||||
version: String,
|
||||
engine: Engine,
|
||||
pre: ProviderPre<HostState>,
|
||||
}
|
||||
|
||||
impl WasmProvider {
|
||||
/// Compile a component from disk and read its metadata once.
|
||||
/// Fails fast if the component does not satisfy the provider world.
|
||||
pub fn load(
|
||||
engine: &Engine,
|
||||
linker: &Linker<HostState>,
|
||||
path: &Path,
|
||||
) -> Result<Self, HostError> {
|
||||
let component = Component::from_file(engine, path)?;
|
||||
let pre = ProviderPre::new(linker.instantiate_pre(&component)?)?;
|
||||
|
||||
let mut provider = Self {
|
||||
name: String::new(),
|
||||
version: String::new(),
|
||||
engine: engine.clone(),
|
||||
pre,
|
||||
};
|
||||
|
||||
let mut store = provider.new_store();
|
||||
let instance = provider.pre.instantiate(&mut store)?;
|
||||
let info = instance
|
||||
.whoareyou_provider_lookup()
|
||||
.call_metadata(&mut store)?;
|
||||
|
||||
provider.name = info.name;
|
||||
provider.version = info.version;
|
||||
|
||||
Ok(provider)
|
||||
}
|
||||
|
||||
pub fn version(&self) -> &str {
|
||||
&self.version
|
||||
}
|
||||
|
||||
fn new_store(&self) -> Store<HostState> {
|
||||
// No preopens, no env, no inherited stdio — fully sandboxed guest.
|
||||
let ctx = WasiCtxBuilder::new().build();
|
||||
|
||||
let mut store = Store::new(
|
||||
&self.engine,
|
||||
HostState {
|
||||
ctx,
|
||||
table: ResourceTable::new(),
|
||||
},
|
||||
);
|
||||
|
||||
store.set_epoch_deadline(EPOCH_DEADLINE_TICKS);
|
||||
|
||||
store
|
||||
}
|
||||
}
|
||||
|
||||
impl ProviderHandle for WasmProvider {
|
||||
fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
|
||||
fn requests(&self, number: &str) -> Result<Vec<String>, HostError> {
|
||||
let mut store = self.new_store();
|
||||
let instance = self.pre.instantiate(&mut store)?;
|
||||
|
||||
let requests = instance
|
||||
.whoareyou_provider_lookup()
|
||||
.call_requests(&mut store, number)?;
|
||||
|
||||
Ok(requests.into_iter().map(|r| r.url).collect())
|
||||
}
|
||||
|
||||
fn parse(&self, number: &str, responses: &[FetchedResponse]) -> ParseOutcome {
|
||||
let wit_responses: Vec<WitResponse> = responses
|
||||
.iter()
|
||||
.map(|r| WitResponse {
|
||||
status: r.status,
|
||||
body: r.body.clone(),
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut store = self.new_store();
|
||||
|
||||
let result: Result<Result<_, WitLookupError>, wasmtime::Error> = (|| {
|
||||
let instance = self.pre.instantiate(&mut store)?;
|
||||
|
||||
instance
|
||||
.whoareyou_provider_lookup()
|
||||
.call_parse(&mut store, number, &wit_responses)
|
||||
})();
|
||||
|
||||
match result {
|
||||
Ok(Ok(entry)) => ParseOutcome::Ok(Entry {
|
||||
messages: entry.messages,
|
||||
history: entry.history,
|
||||
comments: entry
|
||||
.comments
|
||||
.into_iter()
|
||||
.map(|c| Comment {
|
||||
timestamp: c.timestamp,
|
||||
title: c.title,
|
||||
message: c.message,
|
||||
})
|
||||
.collect(),
|
||||
}),
|
||||
Ok(Err(WitLookupError::NoData)) => ParseOutcome::NoData,
|
||||
Ok(Err(WitLookupError::ParseFailed(message))) => ParseOutcome::Failed(message),
|
||||
// Trap (incl. epoch deadline exceeded) or instantiation failure.
|
||||
Err(error) => ParseOutcome::Failed(format!("component error: {error}")),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user