mirror of
https://github.com/outbackdingo/optimclaw.git
synced 2026-08-30 01:19:34 +00:00
perf: speed up startup from ~15s to ~2s (#280)
Three high-impact changes eliminate most startup latency: 1. Enable wasmtime persistent compilation cache — call cache_config_load_default() so compiled native code is serialized to disk (~/.cache/wasmtime). Subsequent startups deserialize instead of recompiling, dropping the WASM phase from ~13s to <1s. 2. Cache compiled Component in PreparedModule — store the compiled wasmtime::component::Component directly instead of raw bytes. Eliminates ~2.6s recompilation on every first tool/channel execution. 3. Move blocking housekeeping to background tasks — embedding backfill (~1.3s of failing HTTP calls) and stale job cleanup are fire-and-forget work that no longer blocks the critical startup path. Also: deduplicate Workspace creation in main.rs (two identical instances reduced to one), and replace leftover println! in session validation with tracing calls. Co-authored-by: Claude Opus 4.6 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
2cdd1acb1e
commit
98ee648fcb
@@ -64,8 +64,8 @@ impl WasmRuntimeConfig {
|
||||
/// A compiled WASM component ready for instantiation.
|
||||
///
|
||||
/// Contains the pre-compiled component plus cached metadata extracted
|
||||
/// from the component during preparation.
|
||||
#[derive(Debug)]
|
||||
/// from the component during preparation. Stores the compiled `Component`
|
||||
/// directly so instantiation doesn't require recompilation.
|
||||
pub struct PreparedModule {
|
||||
/// Tool name.
|
||||
pub name: String,
|
||||
@@ -73,16 +73,26 @@ pub struct PreparedModule {
|
||||
pub description: String,
|
||||
/// Parameter schema JSON (cached from component).
|
||||
pub schema: serde_json::Value,
|
||||
/// Compiled component bytes (can be serialized for caching).
|
||||
component_bytes: Vec<u8>,
|
||||
/// Pre-compiled component (cheaply cloneable via internal Arc).
|
||||
component: wasmtime::component::Component,
|
||||
/// Resource limits for this tool.
|
||||
pub limits: ResourceLimits,
|
||||
}
|
||||
|
||||
impl PreparedModule {
|
||||
/// Get the compiled component bytes.
|
||||
pub fn component_bytes(&self) -> &[u8] {
|
||||
&self.component_bytes
|
||||
/// Get the pre-compiled component for instantiation.
|
||||
pub fn component(&self) -> &wasmtime::component::Component {
|
||||
&self.component
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for PreparedModule {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("PreparedModule")
|
||||
.field("name", &self.name)
|
||||
.field("description", &self.description)
|
||||
.field("limits", &self.limits)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,6 +133,13 @@ impl WasmToolRuntime {
|
||||
// Disable debug info in production for smaller modules
|
||||
wasmtime_config.debug_info(false);
|
||||
|
||||
// Enable persistent compilation cache. Wasmtime serializes compiled native
|
||||
// code to disk (~/.cache/wasmtime by default), so subsequent startups
|
||||
// deserialize instead of recompiling — typically 10-50x faster.
|
||||
if let Err(e) = wasmtime_config.cache_config_load_default() {
|
||||
tracing::warn!("Failed to enable wasmtime compilation cache: {}", e);
|
||||
}
|
||||
|
||||
let engine = Engine::new(&wasmtime_config).map_err(|e| {
|
||||
WasmError::EngineCreationFailed(format!("Failed to create Wasmtime engine: {}", e))
|
||||
})?;
|
||||
@@ -199,7 +216,7 @@ impl WasmToolRuntime {
|
||||
name: name.clone(),
|
||||
description,
|
||||
schema,
|
||||
component_bytes: wasm_bytes,
|
||||
component,
|
||||
limits: limits.unwrap_or(default_limits),
|
||||
})
|
||||
})
|
||||
|
||||
@@ -13,7 +13,7 @@ use std::time::{Duration, Instant};
|
||||
|
||||
use async_trait::async_trait;
|
||||
use wasmtime::Store;
|
||||
use wasmtime::component::{Component, Linker};
|
||||
use wasmtime::component::Linker;
|
||||
use wasmtime_wasi::{ResourceTable, WasiCtx, WasiCtxBuilder, WasiView};
|
||||
|
||||
use crate::context::JobContext;
|
||||
@@ -581,9 +581,8 @@ impl WasmToolWrapper {
|
||||
// Set up resource limiter
|
||||
store.limiter(|data| &mut data.limiter);
|
||||
|
||||
// Compile the component (uses cached bytes)
|
||||
let component = Component::new(engine, self.prepared.component_bytes())
|
||||
.map_err(|e| WasmError::CompilationFailed(e.to_string()))?;
|
||||
// Use the pre-compiled component (no recompilation needed)
|
||||
let component = self.prepared.component().clone();
|
||||
|
||||
// Create linker with all host functions properly namespaced
|
||||
let mut linker = Linker::new(engine);
|
||||
|
||||
Reference in New Issue
Block a user