Expand description
Save and restore VM instance state. Save and restore VM instance state.
This module provides Instance::save_state and
Instance::restore_state for pausing execution at bar N and resuming
from bar N+1 later.
§Server-side best practices
In a server deployment, each running script typically processes thousands of historical bars before reaching the live feed. Replaying all historical bars on every restart is expensive. Snapshots let you checkpoint the VM state after the historical replay, then reload it instantly on the next start.
§Recommended workflow
Cold start
│
├─ Build Instance (InstanceBuilder)
├─ let mut handle = instance.run(symbol, timeframe)
├─ while let Some(e) = handle.next_event().await { … }
├─ handle.save_state() → Vec<u8> (or instance.run_to_end() then save_state())
├─ Persist the bytes (database, object storage, local disk, …)
└─ Continue feeding live bars
Warm restart
│
├─ Load the persisted bytes
├─ let mut instance = Instance::restore_state(&bytes)?
│ .with_data_provider(provider).build()?;
└─ instance.run_to_end() — automatically resumes from the next bar§When to save
The current bar must be confirmed before saving — save_state() returns
SnapshotError::UnconfirmedBar otherwise. Save once after the last
confirmed bar and resave whenever you want to advance the checkpoint.
§Candlestick data
Candlestick data is not included in the snapshot. When run() is
called on a restored instance, the VM automatically passes
last_bar_time + 1 to the data provider so that only new bars are
fetched.
§Versioning and invalidation
Snapshots embed a format version (SNAPSHOT_VERSION) and the compiled
Program. A snapshot is only valid
for the exact binary that created it: a new Navi release, a changed
script, or modified inputs all require discarding the snapshot and
replaying history from scratch.
A simple invalidation strategy: store the snapshot alongside a hash of the Pine source (or the compiled program bytes). On startup, compare the hash; if it differs, delete the snapshot and do a full cold replay.
§Example
use navi_vm::{Instance, snapshot::SnapshotError};
// --- Cold start: replay history and checkpoint ---
let mut instance = build_instance(script, symbol_info, timeframe)
.run_to_end(symbol, timeframe)
.await?;
let snapshot: Vec<u8> = instance.save_state()?; // bar must be confirmed
persist_to_storage(&snapshot);
// --- Warm restart: restore and continue ---
let bytes: Vec<u8> = load_from_storage();
let instance = Instance::restore_state(&bytes)?
.with_data_provider(provider)
.build()?
.run_to_end(symbol, timeframe)
.await?; // auto-resumesStructs§
- Restore
Builder - Builder returned by
Instance::restore_statefor configuring optional parameters before completing the restore.
Enums§
- Snapshot
Error - Errors that can occur during snapshot save/restore.