feat(runtime): cache compiled components

Enable Wasmtime's persistent compilation cache and expose an optional cache directory in RuntimeConfig.

Create and canonicalize the configured directory before Engine construction, and report cache filesystem and configuration failures through dedicated RuntimeError variants.
This commit is contained in:
Maofeng
2026-07-30 07:18:21 +08:00
parent 38a397fa20
commit 53a8c6b690
4 changed files with 132 additions and 21 deletions
Generated
+100 -18
View File
@@ -673,7 +673,7 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1"
dependencies = [
"thiserror",
"thiserror 2.0.19",
]
[[package]]
@@ -1042,6 +1042,27 @@ dependencies = [
"crypto-common",
]
[[package]]
name = "directories-next"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "339ee130d97a610ea5a5872d2bbb130fdf68884ff09d3028b81bec8a1ac23bbc"
dependencies = [
"cfg-if",
"dirs-sys-next",
]
[[package]]
name = "dirs-sys-next"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
dependencies = [
"libc",
"redox_users",
"winapi",
]
[[package]]
name = "displaydoc"
version = "0.2.6"
@@ -1937,7 +1958,7 @@ dependencies = [
"jni-sys",
"log",
"simd_cesu8",
"thiserror",
"thiserror 2.0.19",
"walkdir",
"windows-link",
]
@@ -2057,6 +2078,15 @@ dependencies = [
"cc",
]
[[package]]
name = "libredox"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c943259e342f1e06ff2da7a83eabdfe7f92ce10262688dbf1895ff0b3e6e4652"
dependencies = [
"libc",
]
[[package]]
name = "linkme"
version = "0.3.37"
@@ -2654,7 +2684,7 @@ dependencies = [
"rustc-hash 2.1.3",
"rustls",
"socket2",
"thiserror",
"thiserror 2.0.19",
"tokio",
"tracing",
"web-time",
@@ -2677,7 +2707,7 @@ dependencies = [
"rustls",
"rustls-pki-types",
"slab",
"thiserror",
"thiserror 2.0.19",
"tinyvec",
"tracing",
"web-time",
@@ -2856,6 +2886,17 @@ dependencies = [
"bitflags",
]
[[package]]
name = "redox_users"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
dependencies = [
"getrandom 0.2.17",
"libredox",
"thiserror 1.0.69",
]
[[package]]
name = "regalloc2"
version = "0.13.5"
@@ -3582,7 +3623,7 @@ dependencies = [
"tantivy-stacker",
"tantivy-tokenizer-api",
"tempfile",
"thiserror",
"thiserror 2.0.19",
"time",
"typetag",
"uuid",
@@ -3718,13 +3759,33 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "thiserror"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
dependencies = [
"thiserror-impl 1.0.69",
]
[[package]]
name = "thiserror"
version = "2.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09a43598840e33d5b0331f38c5e30d13bb11c11210a4b58f0d9b18a5a5eefcd9"
dependencies = [
"thiserror-impl",
"thiserror-impl 2.0.19",
]
[[package]]
name = "thiserror-impl"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.119",
]
[[package]]
@@ -4084,7 +4145,7 @@ checksum = "050686193eb999b4bb3bc2acfa891a13da00f79734704c4b8b4ef1a10b368a3c"
dependencies = [
"crossbeam-channel",
"symlink",
"thiserror",
"thiserror 2.0.19",
"time",
"tracing-subscriber",
]
@@ -4152,7 +4213,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b6c49aecd4abae3ffa88ab1e28b3de7a7497a9732be828e3a6f1855b6ea80fd"
dependencies = [
"mimalloc",
"thiserror",
"thiserror 2.0.19",
"tracing",
"tracing-subscriber",
"turso_core",
@@ -4219,7 +4280,7 @@ dependencies = [
"strum_macros",
"tantivy",
"tempfile",
"thiserror",
"thiserror 2.0.19",
"tracing",
"tracing-subscriber",
"turso_ext",
@@ -4264,7 +4325,7 @@ dependencies = [
"miette",
"strum",
"strum_macros",
"thiserror",
"thiserror 2.0.19",
"turso_macros",
]
@@ -4312,7 +4373,7 @@ dependencies = [
"roaring",
"serde",
"serde_json",
"thiserror",
"thiserror 2.0.19",
"tracing",
"turso_core",
"turso_parser",
@@ -4645,7 +4706,7 @@ dependencies = [
"serde",
"serde_json",
"tempfile",
"thiserror",
"thiserror 2.0.19",
"toasty",
"toasty-driver-turso",
"tokio",
@@ -4668,7 +4729,7 @@ dependencies = [
"serde_json",
"sha2",
"tempfile",
"thiserror",
"thiserror 2.0.19",
"toml",
"wit-component 0.243.0",
"wit-parser 0.243.0",
@@ -4680,7 +4741,7 @@ name = "wasmeld-runtime"
version = "0.1.0"
dependencies = [
"serde",
"thiserror",
"thiserror 2.0.19",
"toml",
"wasmeld-package",
"wasmtime",
@@ -4755,6 +4816,7 @@ dependencies = [
"target-lexicon",
"wasmparser 0.243.0",
"wasmtime-environ",
"wasmtime-internal-cache",
"wasmtime-internal-component-macro",
"wasmtime-internal-component-util",
"wasmtime-internal-cranelift",
@@ -4794,6 +4856,26 @@ dependencies = [
"wasmtime-internal-component-util",
]
[[package]]
name = "wasmtime-internal-cache"
version = "41.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a31a582632f47753e4a9a5412ab5edfbc05a6df9031336a2f2eff46a70a1cac"
dependencies = [
"base64 0.22.1",
"directories-next",
"log",
"postcard",
"rustix 1.1.4",
"serde",
"serde_derive",
"sha2",
"toml",
"wasmtime-environ",
"windows-sys 0.61.2",
"zstd",
]
[[package]]
name = "wasmtime-internal-component-macro"
version = "41.0.0"
@@ -4834,7 +4916,7 @@ dependencies = [
"pulley-interpreter",
"smallvec",
"target-lexicon",
"thiserror",
"thiserror 2.0.19",
"wasmparser 0.243.0",
"wasmtime-environ",
"wasmtime-internal-math",
@@ -4969,7 +5051,7 @@ dependencies = [
"io-lifetimes",
"rustix 1.1.4",
"system-interface",
"thiserror",
"thiserror 2.0.19",
"tokio",
"tracing",
"url",
@@ -5076,7 +5158,7 @@ dependencies = [
"regalloc2",
"smallvec",
"target-lexicon",
"thiserror",
"thiserror 2.0.19",
"wasmparser 0.243.0",
"wasmtime-environ",
"wasmtime-internal-cranelift",
@@ -5540,7 +5622,7 @@ dependencies = [
"flate2",
"indexmap",
"memchr",
"thiserror",
"thiserror 2.0.19",
"zopfli",
]
+1 -1
View File
@@ -35,7 +35,7 @@ toml = "0.9.8"
tower-http = { version = "0.7.0", features = ["cors", "trace"] }
tracing = "0.1.44"
tracing-subscriber = { version = "0.3.23", features = ["env-filter", "fmt"] }
wasmtime = { version = "=41.0.0", default-features = false, features = ["component-model", "cranelift", "runtime", "std"] }
wasmtime = { version = "=41.0.0", default-features = false, features = ["cache", "component-model", "cranelift", "runtime", "std"] }
wasmtime-wasi = { version = "=41.0.0", default-features = false, features = ["p2"] }
wit-bindgen = "=0.41.0"
wit-component = "=0.243.0"
+11 -1
View File
@@ -1,6 +1,6 @@
//! Runtime error taxonomy exposed to management layers.
use std::time::Duration;
use std::{path::PathBuf, time::Duration};
use thiserror::Error;
@@ -36,6 +36,16 @@ pub enum RuntimeError {
#[error("runtime creation failed: {0}")]
RuntimeCreation(#[source] wasmtime::Error),
#[error("failed to prepare Component compilation cache {path}: {source}")]
CacheDirectory {
path: PathBuf,
#[source]
source: std::io::Error,
},
#[error("invalid Component compilation cache configuration: {0}")]
CacheConfiguration(#[source] wasmtime::Error),
#[error("failed to read component artifact {path}: {source}")]
ArtifactRead {
path: String,
+20 -1
View File
@@ -8,6 +8,7 @@
use std::{
collections::HashMap,
fs,
path::PathBuf,
sync::{
Arc, Mutex,
atomic::{AtomicBool, Ordering},
@@ -18,7 +19,7 @@ use std::{
};
use wasmtime::{
Config, Engine, Store, StoreLimits, StoreLimitsBuilder,
Cache, CacheConfig, Config, Engine, Store, StoreLimits, StoreLimitsBuilder,
component::{Component, HasData, Linker, ResourceTable},
};
use wasmtime_wasi::{
@@ -61,6 +62,8 @@ pub struct RuntimeConfig {
pub epoch_tick: Duration,
/// Maximum native stack reservation for WebAssembly execution.
pub max_wasm_stack: usize,
/// Optional persistent cache for compiled Component machine code.
pub component_cache_dir: Option<PathBuf>,
/// Service-scoped storage used by Components importing the KV capability.
pub kv_backend: Option<Arc<dyn KvBackend>>,
}
@@ -70,6 +73,7 @@ impl Default for RuntimeConfig {
Self {
epoch_tick: DEFAULT_EPOCH_TICK,
max_wasm_stack: DEFAULT_MAX_WASM_STACK,
component_cache_dir: None,
kv_backend: None,
}
}
@@ -180,6 +184,21 @@ impl Runtime {
wasmtime_config.consume_fuel(true);
wasmtime_config.epoch_interruption(true);
wasmtime_config.max_wasm_stack(config.max_wasm_stack);
if let Some(cache_dir) = &config.component_cache_dir {
fs::create_dir_all(cache_dir).map_err(|source| RuntimeError::CacheDirectory {
path: cache_dir.clone(),
source,
})?;
let cache_dir =
fs::canonicalize(cache_dir).map_err(|source| RuntimeError::CacheDirectory {
path: cache_dir.clone(),
source,
})?;
let mut cache_config = CacheConfig::new();
cache_config.with_directory(cache_dir);
let cache = Cache::new(cache_config).map_err(RuntimeError::CacheConfiguration)?;
wasmtime_config.cache(Some(cache));
}
let engine =
Arc::new(Engine::new(&wasmtime_config).map_err(RuntimeError::RuntimeCreation)?);