From 6842ceee531eaaed66fd73fb3e45442fc79ad713 Mon Sep 17 00:00:00 2001 From: Jorge Prendes Date: Thu, 19 Dec 2024 13:18:13 +0000 Subject: [PATCH] memoize the engine Signed-off-by: Jorge Prendes --- .../containerd-shim-wasmtime/src/instance.rs | 75 +++++++++---------- crates/containerd-shim-wasmtime/src/main.rs | 1 + crates/containerd-shim-wasmtime/src/tests.rs | 19 +---- 3 files changed, 37 insertions(+), 58 deletions(-) diff --git a/crates/containerd-shim-wasmtime/src/instance.rs b/crates/containerd-shim-wasmtime/src/instance.rs index 6d7dc0f18..412202018 100644 --- a/crates/containerd-shim-wasmtime/src/instance.rs +++ b/crates/containerd-shim-wasmtime/src/instance.rs @@ -1,6 +1,5 @@ use std::collections::hash_map::DefaultHasher; use std::hash::{Hash, Hasher}; -use std::marker::PhantomData; use std::sync::LazyLock; use anyhow::{bail, Context, Result}; @@ -21,7 +20,12 @@ use wasmtime_wasi_http::{WasiHttpCtx, WasiHttpView}; use crate::http_proxy::serve_conn; -pub type WasmtimeInstance = Instance>; +pub type WasmtimeInstance = Instance; + +pub fn init() { + // The default engine is memoize, cache it now. + let _ = WasmtimeEngine::default(); +} static PRECOMPILER: LazyLock = LazyLock::new(|| { let mut config = wasmtime::Config::new(); @@ -67,44 +71,34 @@ impl<'a> ComponentTarget<'a> { } #[derive(Clone)] -pub struct WasmtimeEngine { +pub struct WasmtimeEngine { engine: wasmtime::Engine, cancel: CancellationToken, - config_type: PhantomData, -} - -#[derive(Clone)] -pub struct DefaultConfig {} - -impl WasiConfig for DefaultConfig { - fn new_config() -> Config { - let mut config = wasmtime::Config::new(); - config.wasm_component_model(true); // enable component linking - config - } } -pub trait WasiConfig: Clone + Sync + Send + 'static { - fn new_config() -> Config; -} - -impl Default for WasmtimeEngine { +impl Default for WasmtimeEngine { fn default() -> Self { - let mut config = T::new_config(); - config.async_support(true); // must be on + static ENGINE: LazyLock = LazyLock::new(|| { + let mut config = wasmtime::Config::new(); + config.async_support(true); // must be on - if use_pooling_allocator_by_default().unwrap_or_default() { - let cfg = wasmtime::PoolingAllocationConfig::default(); - config.allocation_strategy(wasmtime::InstanceAllocationStrategy::Pooling(cfg)); - } + // Disable Wasmtime parallel compilation for the tests + // see https://github.com/containerd/runwasi/pull/405#issuecomment-1928468714 for details + config.parallel_compilation(!cfg!(test)); - Self { - engine: wasmtime::Engine::new(&config) - .context("failed to create wasmtime engine") - .unwrap(), - cancel: CancellationToken::new(), - config_type: PhantomData, - } + if use_pooling_allocator_by_default() { + let cfg = wasmtime::PoolingAllocationConfig::default(); + config.allocation_strategy(wasmtime::InstanceAllocationStrategy::Pooling(cfg)); + } + + WasmtimeEngine { + engine: wasmtime::Engine::new(&config) + .context("failed to create wasmtime engine") + .unwrap(), + cancel: CancellationToken::new(), + } + }); + ENGINE.clone() } } @@ -145,7 +139,7 @@ impl WasiHttpView for WasiPreview2Ctx { } } -impl Engine for WasmtimeEngine { +impl Engine for WasmtimeEngine { fn name() -> &'static str { "wasmtime" } @@ -199,10 +193,7 @@ impl Engine for WasmtimeEngine { } } -impl WasmtimeEngine -where - T: std::clone::Clone + Sync + WasiConfig + Send + 'static, -{ +impl WasmtimeEngine { /// Execute a wasm module. /// /// This function adds wasi_preview1 to the linker and can be utilized @@ -460,16 +451,18 @@ async fn wait_for_signal() -> Result { /// The pooling allocator is tailor made for the `wasi/http` use case. Check if we can use it. /// /// For more details refer to: -fn use_pooling_allocator_by_default() -> Result { +fn use_pooling_allocator_by_default() -> bool { const BITS_TO_TEST: u32 = 42; let mut config = Config::new(); config.wasm_memory64(true); config.static_memory_maximum_size(1 << BITS_TO_TEST); - let engine = wasmtime::Engine::new(&config)?; + let Ok(engine) = wasmtime::Engine::new(&config) else { + return false; + }; let mut store = Store::new(&engine, ()); let ty = wasmtime::MemoryType::new64(0, Some(1 << (BITS_TO_TEST - 16))); - Ok(wasmtime::Memory::new(&mut store, ty).is_ok()) + wasmtime::Memory::new(&mut store, ty).is_ok() } pub trait IntoErrorCode { diff --git a/crates/containerd-shim-wasmtime/src/main.rs b/crates/containerd-shim-wasmtime/src/main.rs index ccbcb6137..6b1b726dc 100644 --- a/crates/containerd-shim-wasmtime/src/main.rs +++ b/crates/containerd-shim-wasmtime/src/main.rs @@ -2,5 +2,6 @@ use containerd_shim_wasm::sandbox::cli::{revision, shim_main, version}; use containerd_shim_wasmtime::WasmtimeInstance; fn main() { + containerd_shim_wasmtime::instance::init(); shim_main::("wasmtime", version!(), revision!(), "v1", None); } diff --git a/crates/containerd-shim-wasmtime/src/tests.rs b/crates/containerd-shim-wasmtime/src/tests.rs index 79ea0550e..54f03eaa4 100644 --- a/crates/containerd-shim-wasmtime/src/tests.rs +++ b/crates/containerd-shim-wasmtime/src/tests.rs @@ -4,28 +4,13 @@ use containerd_shim_wasm::container::Instance; use containerd_shim_wasm::testing::modules::*; use containerd_shim_wasm::testing::{oci_helpers, WasiTest}; use serial_test::serial; -use wasmtime::Config; use WasmtimeTestInstance as WasiInstance; -use crate::instance::{WasiConfig, WasmtimeEngine}; +use crate::instance::WasmtimeEngine; // use test configuration to avoid dead locks when running tests // https://github.com/containerd/runwasi/issues/357 -type WasmtimeTestInstance = Instance>; - -#[derive(Clone)] -struct WasiTestConfig {} - -impl WasiConfig for WasiTestConfig { - fn new_config() -> Config { - let mut config = wasmtime::Config::new(); - // Disable Wasmtime parallel compilation for the tests - // see https://github.com/containerd/runwasi/pull/405#issuecomment-1928468714 for details - config.parallel_compilation(false); - config.wasm_component_model(true); // enable component linking - config - } -} +type WasmtimeTestInstance = Instance; #[test] #[serial]