Skip to main content

Crate microvm_warm_pool

Crate microvm_warm_pool 

Source
Expand description

Pre-restored Firecracker microVM pool harness.

Sits on top of microvm_runtime and turns a snapshot-restore-then-boot flow into a hashmap lookup. Acquire wallclock drops from ~150 ms (cold) to ~10 ms (warm).

The pool is bucketed by StackKey (stack_name, version, vcpu_count, mem_size_mib) — different identities are not interchangeable, so each gets its own queue. A single background refill thread keeps every registered bucket between min_depth and max_depth entries, evicts entries older than entry_max_age, and drops entries whose EntryValidator reports them unhealthy.

See pool::WarmPool for the entry point.

§Required host environment

Warm handoff with network rewrite requires Firecracker 1.10+ (the version that honors network_interfaces overrides in PUT /snapshot/load). The pool itself runs anywhere; it is the provider you pass in that needs the KVM-capable Linux host.

§Example

use std::sync::Arc;
use std::time::Duration;
use microvm_runtime::{
    InMemoryVmProvider,
    model::{NetworkInterface, SnapshotRef},
};
use microvm_warm_pool::{
    EntryValidator, StackKey, ValidationResult, WarmPool, WarmPoolConfig,
};

struct AlwaysHealthy;
impl EntryValidator for AlwaysHealthy {
    fn validate(&self, _vm_id: &str) -> ValidationResult {
        ValidationResult::Healthy
    }
}

let provider = InMemoryVmProvider::default();
let pool = WarmPool::start(
    provider,
    WarmPoolConfig {
        min_depth: 2,
        max_depth: 4,
        refill_interval: Duration::from_secs(5),
        entry_max_age: Duration::from_secs(600),
    },
    Arc::new(AlwaysHealthy),
);

let stack = StackKey {
    stack_name: "node20".into(),
    version: "1.4.2".into(),
    vcpu_count: 2,
    mem_size_mib: 512,
};
pool.register(
    stack.clone(),
    SnapshotRef {
        vm_id: "template-vm".into(),
        snapshot_id: "template-snap".into(),
        resume_immediately: true,
        network_overrides: Vec::new(),
    },
);

// Caller side at acquire time: pop a warm entry, then bring up a
// tenant-specific VM by restoring the same snapshot with the per-tenant
// network override. If `acquire` returns `None`, fall back to cold boot.
if let Some(handle) = pool.acquire(&stack) {
    let _ = handle; // restore with handle.source_snapshot + your overrides
}

Re-exports§

pub use pool::EntryValidator;
pub use pool::ValidationResult;
pub use pool::WarmPool;
pub use pool::WarmPoolConfig;
pub use pool::WarmPoolHandle;
pub use pool::WarmPoolMetrics;
pub use stack_key::StackKey;

Modules§

pool
Warm pool harness.
stack_key
Bucket identifier for warm pool entries.