{"record":{"id":"b2861578860bb748","repo":"nautechsystems/nautilus_trader","slug":"binance-spot-public-json-stream-pool-shutdown-bega","errorCode":null,"errorMessage":"Binance Spot public JSON stream pool shutdown began during connect","messagePattern":"Binance Spot public JSON stream pool shutdown began during connect","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/binance/src/spot/websocket/public_json/client.rs","lineNumber":204,"sourceCode":"            self.signal.store(false, Ordering::Release);\n        }\n\n        let (out_tx, out_rx) = tokio::sync::mpsc::unbounded_channel();\n        *self.out_tx.lock() = Some(out_tx);\n        *self.out_rx.lock() = Some(out_rx);\n\n        let slot = self.create_connection(0).await?;\n        let shutdown = {\n            let mut slots = self.slots.lock();\n            let shutdown = self.signal.load(Ordering::Acquire);\n            slots.push(slot);\n            shutdown\n        };\n\n        if shutdown {\n            let rollback = self.close_connections().await;\n            return Err(match rollback {\n                Ok(()) => anyhow::anyhow!(\n                    \"Binance Spot public JSON stream pool shutdown began during connect\"\n                ),\n                Err(e) => anyhow::anyhow!(\n                    \"Binance Spot public JSON stream pool shutdown began during connect; rollback failed: {e}\"\n                ),\n            });\n        }\n\n        log::debug!(\n            \"Connected to Binance Spot public JSON stream pool: url={}\",\n            self.url\n        );\n        Ok(())\n    }\n\n    /// Closes all WebSocket connections and tasks.\n    ///\n    /// # Errors","sourceCodeStart":186,"sourceCodeEnd":222,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/binance/src/spot/websocket/public_json/client.rs#L186-L222","documentation":"During connect() on the Binance Spot public JSON WebSocket stream pool, the pool's shutdown flag was set while the connect sequence was in progress. The method detects this race, rolls back by closing any connections it had opened, and fails with this error rather than returning a half-connected pool. It is a deliberate invalid-state guard, not a network failure.","triggerScenarios":"Calling connect() on the public JSON stream pool concurrently with (or immediately before) shutdown() / pool teardown — the shutdown flag flips between the connect start and the shutdown check at client.rs:204, including the rollback-failed variant when close_connections() also errors.","commonSituations":"Stop/teardown of the node or adapter racing a (re)connect attempt from another task; caller initiating connect after initiating shutdown on a reconnect path; a shutdown triggered by an unrelated fault arriving while a reconnect loop is dialing.","solutions":["Serialize lifecycle calls: do not call connect() after or concurrently with shutdown(); await the shutdown before tearing down.","Treat this error as terminal for the pool — create a new stream pool instance instead of retrying connect on the same one.","If reconnect logic is in use, check the shutdown flag before each reconnect attempt and bail out when the pool is shutting down.","If the rollback-failed variant appears, also investigate why close_connections() errored (stuck sockets/tasks) during teardown."],"exampleFix":"// before\npool.connect().await?; // may race shutdown\n// after\nif pool.is_shutdown() {\n    return Ok(()); // pool terminated; do not reconnect\n}\npool.connect().await?;","handlingStrategy":"type-guard","validationCode":"// before connecting, check lifecycle state\nfn can_connect(shutdown: std::sync::atomic::AtomicBool) -> bool {\n    !shutdown.load(std::sync::atomic::Ordering::Acquire)\n}","typeGuard":"fn pool_is_live(pool: &StreamPool) -> bool {\n    !pool.is_shutdown()\n}","tryCatchPattern":"match pool.connect().await {\n    Ok(()) => { /* stream */ }\n    Err(e) if e.to_string().contains(\"shutdown began during connect\") => {\n        // pool terminated: do not retry this instance; recreate pool if streaming is still wanted\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Serialize pool lifecycle: never run connect() concurrently with shutdown()/teardown.","Check the shutdown flag before each reconnect attempt in reconnect loops.","Treat this error as terminal — build a fresh pool rather than retrying the old one.","Ensure a single owner task drives connect/shutdown to eliminate the race."],"tags":["websocket","lifecycle","race-condition","binance-spot","shutdown"],"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"}