{"record":{"id":"b0b459f63eb1301e","repo":"nautechsystems/nautilus_trader","slug":"failed-to-terminate-deribit-session-tasks-e","errorCode":null,"errorMessage":"Failed to terminate Deribit session tasks: {e}","messagePattern":"Failed to terminate Deribit session tasks: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/deribit/src/execution.rs","lineNumber":209,"sourceCode":"        self.session_tasks.begin_shutdown();\n        self.ws_client.begin_shutdown();\n    }\n\n    async fn await_pending_tasks(&self) -> anyhow::Result<()> {\n        self.pending_tasks.begin_shutdown();\n        self.pending_tasks\n            .finish_shutdown(Duration::from_secs(1), Duration::from_secs(2))\n            .await\n            .map_err(|e| anyhow::anyhow!(\"Failed to terminate Deribit execution tasks: {e}\"))?;\n        Ok(())\n    }\n\n    async fn await_session_tasks(&self) -> anyhow::Result<()> {\n        self.session_tasks.begin_shutdown();\n        self.session_tasks\n            .finish_shutdown(Duration::from_secs(1), Duration::from_secs(2))\n            .await\n            .map_err(|e| anyhow::anyhow!(\"Failed to terminate Deribit session tasks: {e}\"))?;\n        Ok(())\n    }\n\n    async fn teardown_partial_connect(&self) -> anyhow::Result<()> {\n        self.abort_session_tasks();\n        self.abort_pending_tasks();\n\n        let mut errors = Vec::new();\n        if let Err(e) = self.ws_client.close().await {\n            errors.push(format!(\"WebSocket shutdown failed: {e}\"));\n        }\n        let (session_result, pending_result) =\n            tokio::join!(self.await_session_tasks(), self.await_pending_tasks());\n\n        if let Err(e) = session_result {\n            errors.push(e.to_string());\n        }\n","sourceCodeStart":191,"sourceCodeEnd":227,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/deribit/src/execution.rs#L191-L227","documentation":"`await_session_tasks` finishes all session-scoped tasks (message-processing loops) within 1s/2s deadlines during shutdown. If they can't be terminated in time, the error at execution.rs:209 is raised, propagated out of `connect()` when it needs a clean slate for a new session. It means lingering session tasks blocked a fresh session start.","triggerScenarios":"Reconnecting the execution client while prior session task loops are still alive and exceed the shutdown deadlines; session tasks blocked awaiting WebSocket messages on a stalled connection.","commonSituations":"Reconnect after network drop where the old read loop is wedged; many short-lived reconnects stacking session tasks; async runtime starvation preventing tasks from observing the shutdown signal within 2 seconds.","solutions":["Force-abort session tasks (`abort_session_tasks`) before reconnecting, then retry connect.","Retry connect after a brief backoff to let wedged tasks unwind.","Check for a stalled WebSocket or missing read-timeout causing session loops to hang.","If the runtime is overloaded, reduce concurrency or use a fresh execution client per session."],"exampleFix":"// before\nclient.connect().await?;\n\n// after\nif let Err(e) = client.connect().await {\n    if e.to_string().contains(\"Failed to terminate Deribit session tasks\") {\n        client.abort_session_tasks();\n        tokio::time::sleep(Duration::from_millis(200)).await;\n    }\n    client.connect().await?;\n}","handlingStrategy":"retry","validationCode":"// Pre-check: don't reconnect while a previous shutdown is still settling\nassert!(last_shutdown_complete.load(Ordering::SeqCst), \"previous shutdown still in progress\");","typeGuard":null,"tryCatchPattern":"if let Err(e) = client.connect().await {\n    if e.to_string().contains(\"Failed to terminate Deribit session tasks\") {\n        client.abort_session_tasks();\n        tokio::time::sleep(Duration::from_millis(200)).await;\n        client.connect().await?;\n    } else {\n        return Err(e);\n    }\n}","preventionTips":["Await full shutdown completion before starting a new connect.","Force-abort session tasks on shutdown timeouts instead of immediately reconnecting.","Keep the async runtime responsive (avoid blocking calls in session loops).","Configure WebSocket read timeouts so message loops can't wedge forever."],"tags":["task-shutdown","timeout","reconnect","deribit"],"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"}