nautechsystems/nautilus_trader · error
spawn
Error message
spawn
What it means
EventStoreWriter::spawn starts the background writer thread that drains the submit channel and commits batches to the backend. The expect at writer/mod.rs:1131 (test submit_signals_halt_when_stalled_past_threshold) panics if spawn fails. Spawn errors when the run/backend is not in an open, writable state, so the thread could not be started safely.
Source
Thrown at crates/event_store/src/writer/mod.rs:1131
let appends_seen = Arc::new(AtomicUsize::new(0));
let backend = BlockingBackend::new(
Arc::clone(&inner),
Arc::clone(&gate),
Arc::clone(&appends_seen),
);
let halt_threshold = Duration::from_millis(50);
let config = WriterConfig {
channel_capacity: 1,
max_batch_entries: 1,
max_batch_latency: Duration::from_millis(1),
halt_threshold,
};
let clock = get_atomic_clock_static();
let boxed = Box::new(backend);
let writer = EventStoreWriter::spawn(boxed, clock, halt, config).expect("spawn");
// First submit fits in the channel; the writer thread takes it and blocks.
writer.submit(entry_draft(10)).expect("first submit fits");
// Wait long enough for the writer to dequeue and become blocked at the gate.
std::thread::sleep(Duration::from_millis(20));
// Second and third submits saturate the slot; the channel buffer holds one,
// the next one stalls past the halt threshold.
let _ = writer.submit(entry_draft(11));
let stalled = writer.submit(entry_draft(12)).expect_err("must stall");
match stalled {
SubmitError::HaltSignaled { .. } => {}
SubmitError::Closed => panic!("expected HaltSignaled, was Closed"),
}
let captured_reasons = captured.lock();
assert_eq!(View on GitHub (pinned to 18893faf8b)
Solutions
- Call backend.open_run(manifest(...)) before EventStoreWriter::spawn and check its Result
- Ensure the backend's manifest()/high_watermark() return Ok during initialization
- Confirm the run status is Open, not already Sealed/Ended
- Validate WriterConfig (channel_capacity, thresholds) before spawn
Example fix
// before
let writer = EventStoreWriter::spawn(boxed, clock, halt, config).expect("spawn");
// after
let writer = EventStoreWriter::spawn(boxed, clock, halt, config)
.unwrap_or_else(|e| panic!("writer spawn failed: {e:?}")); Defensive patterns
Strategy: validation
Validate before calling
let m = backend.manifest().map_err(|e| format!("backend init query failed: {e}"))?;
assert_eq!(m.status, RunStatus::Open, "spawn requires an open run"); Type guard
fn can_spawn_writer(m: &RunManifest) -> bool {
m.status == RunStatus::Open
} Try / catch
match EventStoreWriter::spawn(boxed, clock, halt, config) {
Ok(writer) => { /* use writer */ }
Err(e) => eprintln!("spawn failed: {e:?}"),
} Prevention
- Open the run before spawning
- Ensure backend manifest()/high_watermark() succeed at init
- Validate WriterConfig before spawn
When it happens
Trigger: Calling EventStoreWriter::spawn(boxed, clock, halt, config) with a backend whose run was never opened, a backend that fails initialization (manifest/high_watermark calls error), or invalid WriterConfig values.
Common situations: Constructing a writer for halt-threshold tests with channel_capacity=1 and a gated backend before opening the run; passing a failing backend (e.g. manifest() -> Err(Backend("disk failure"))) to spawn; reusing a backend whose run is already sealed.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/a81f633f2aeb24f8.
Report an issue: GitHub.