{"record":{"id":"bc5c9761384b915c","repo":"nautechsystems/nautilus_trader","slug":"submit","errorCode":null,"errorMessage":"submit","messagePattern":"submit","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/event_store/src/writer/mod.rs","lineNumber":1686,"sourceCode":"        // surface at close drain, masking the steady-state batching contract.\n        let (halt, _) = captured_halt;\n        let (wrapper, shared) = SharedMemory::new();\n        shared.lock().open_run(manifest(\"run-time\")).expect(\"open\");\n\n        let writer = EventStoreWriter::spawn(\n            Box::new(wrapper),\n            get_atomic_clock_static(),\n            halt,\n            WriterConfig {\n                channel_capacity: 32,\n                max_batch_entries: 100,\n                max_batch_latency: Duration::from_millis(20),\n                halt_threshold: Duration::from_secs(30),\n            },\n        )\n        .expect(\"spawn\");\n\n        writer.submit(entry_draft(10)).expect(\"submit\");\n\n        // Wait long enough that the latency window has elapsed multiple times.\n        let mut waited = Duration::ZERO;\n        while writer.high_watermark() == 0 && waited < Duration::from_millis(500) {\n            std::thread::sleep(Duration::from_millis(5));\n            waited += Duration::from_millis(5);\n        }\n        assert_eq!(\n            writer.high_watermark(),\n            1,\n            \"latency window must commit a sub-batch entry before close\",\n        );\n\n        let final_hwm = writer.close(run_ended_draft()).expect(\"close\");\n        assert_eq!(final_hwm, 2);\n    }\n\n    #[rstest]","sourceCodeStart":1668,"sourceCodeEnd":1704,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/event_store/src/writer/mod.rs#L1668-L1704","documentation":"This is a test panic from `.expect(\"submit\")` on `EventStoreWriter::submit`, which returns `SubmitError` on failure. The library returns `SubmitError::Closed` when the writer is shut down, the writer thread has exited, or a prior halt already fired (halt is terminal for the run), and `SubmitError::HaltSignaled` when the submit blocked longer than the configured `halt_threshold` due to backpressure. In this latency-window test, a stall past the 30s halt threshold or an unexpected writer shutdown panics.","triggerScenarios":"Calling `submit` after the writer thread exited or a halt was signaled; the entry channel staying full past `WriterConfig::halt_threshold` (e.g. backend `append_batch` commits stall longer than 30s); calling submit after `close` or after another submit stalled.","commonSituations":"A slow or blocked backend making the bounded channel back up; reusing a writer after a halt was latched by an earlier stall; tests with artificially tiny `max_batch_latency`/`halt_threshold` configs; spawning without an open run so the writer thread dies immediately.","solutions":["Ensure the backend has an open run before `EventStoreWriter::spawn` and that `append_batch` can commit promptly.","Increase `WriterConfig::halt_threshold` or `channel_capacity` if legitimate bursts cause backpressure stalls.","Never call `submit` after a halt fired or after `close`; check `high_watermark()`/halt state first.","Match on the returned `SubmitError` (`Closed` vs `HaltSignaled`) and log `stalled_for`/`threshold` to identify which path fired."],"exampleFix":"// before\nwriter.submit(entry_draft(10)).expect(\"submit\");\n// after\nmatch writer.submit(entry_draft(10)) {\n    Ok(()) => {}\n    Err(SubmitError::Closed) => panic!(\"writer closed/halted before submit\"),\n    Err(SubmitError::HaltSignaled { stalled_for, threshold }) => {\n        panic!(\"submit stalled {stalled_for:?} > {threshold:?}\")\n    }\n}","handlingStrategy":"try-catch","validationCode":"// before submitting\nif writer_halted.load(Ordering::Acquire) { return; }\nassert!(backend_has_open_run, \"open_run must precede writer spawn\");","typeGuard":"fn is_halt_signaled(e: &SubmitError) -> bool { matches!(e, SubmitError::HaltSignaled { .. }) }","tryCatchPattern":"match writer.submit(draft) {\n    Ok(()) => {}\n    Err(SubmitError::Closed) => log::warn!(\"writer closed; dropping entry\"),\n    Err(SubmitError::HaltSignaled { stalled_for, threshold }) => {\n        log::error!(\"submit stalled {stalled_for:?} > {threshold:?}; halting run\");\n    }\n}","preventionTips":["Always open a run on the backend before spawning the writer.","Size channel_capacity and halt_threshold above worst-case commit latency.","Treat a fired halt as terminal: never submit afterwards.","Log SubmitError variants to distinguish closed vs stalled paths."],"tags":["rust","writer","backpressure","halt"],"backgroundTag":"invalid-state-transition","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}