{"record":{"id":"063a44d10f7399b7","repo":"nautechsystems/nautilus_trader","slug":"binance-spot-public-json-stream-pool-shutdown-bega-063a44","errorCode":null,"errorMessage":"Binance Spot public JSON stream pool shutdown began during subscribe","messagePattern":"Binance Spot public JSON stream pool shutdown began during subscribe","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/binance/src/spot/websocket/public_json/client.rs","lineNumber":349,"sourceCode":"            };\n\n            if remaining_capacity >= new_streams.len() || slot_count >= MAX_CONNECTIONS {\n                break;\n            }\n\n            let new_slot = self.create_connection(slot_count).await?;\n            let (slot_count, shutdown) = {\n                let mut slots = self.slots.lock();\n                let shutdown = self.signal.load(Ordering::Acquire);\n                slots.push(new_slot);\n                (slots.len(), shutdown)\n            };\n\n            if shutdown {\n                let client = self.clone();\n                let rollback = client.close_connections().await;\n                return Err(match rollback {\n                    Ok(()) => anyhow::anyhow!(\n                        \"Binance Spot public JSON stream pool shutdown began during subscribe\"\n                    ),\n                    Err(e) => anyhow::anyhow!(\n                        \"Binance Spot public JSON stream pool shutdown began during subscribe; rollback failed: {e}\"\n                    ),\n                });\n            }\n            log::debug!(\n                \"Spot JSON pool slot {} connected: url={}\",\n                slot_count - 1,\n                self.url\n            );\n        }\n\n        // Phase 3: stage assignments, send commands, then commit slot state.\n        let mut slots = self.slots.lock();\n\n        if self.signal.load(Ordering::Acquire) {","sourceCodeStart":331,"sourceCodeEnd":367,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/binance/src/spot/websocket/public_json/client.rs#L331-L367","documentation":"The pool observed its shutdown flag while a subscribe() call was in progress; the client rolled back by closing connections and returned this error because rollback succeeded. It guarantees no new subscriptions are added to a pool that is being torn down.","triggerScenarios":"Calling subscribe() on the public JSON pool concurrently with close_connections()/shutdown; the shutdown flag is set after the subscription batching begins but before commands are dispatched.","commonSituations":"Stopping a data engine or actor while quote/kline subscription requests are still queued; application shutdown ordering where the market-data client is stopped before dependent subscribers finish subscribing.","solutions":["Await all pending subscribe() futures before calling close_connections()/shutdown.","Treat this error as benign during shutdown: check the pool's shutdown state and skip retrying if teardown was intentional.","Reorder component stop: cancel subscription tasks first, then shut down the pool.","If rollback errors also appear, inspect handler task lifetimes so close_connections() is only called once."],"exampleFix":"// before\nclient.subscribe(streams).await?; // races shutdown\nclient.close_connections().await;\n\n// after\nif !client.is_shutdown() {\n    client.subscribe(streams).await?;\n}\nclient.close_connections().await;","handlingStrategy":"try-catch","validationCode":"if pool.is_shutdown() {\n    return; // skip subscribe during shutdown\n}","typeGuard":null,"tryCatchPattern":"match client.subscribe(streams).await {\n    Err(e) if e.to_string().contains(\"shutdown began during subscribe\") => {\n        log::debug!(\"subscribe aborted by shutdown\");\n    }\n    Err(e) => return Err(e),\n    Ok(v) => Ok(v),\n}","preventionTips":["Sequence teardown: finish subscriptions before closing the pool.","Gate subscribe calls on the pool's shutdown state.","Avoid stopping the data engine while subscription requests are pending.","Supervise subscriber tasks and cancel them before pool shutdown."],"tags":["race-condition","shutdown","websocket","subscription"],"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-14T05:17:10.506Z"}