{"record":{"id":"6ba8bf3c79c486b4","repo":"nautechsystems/nautilus_trader","slug":"failed-to-terminate-tardis-tasks-e","errorCode":null,"errorMessage":"Failed to terminate Tardis tasks: {e}","messagePattern":"Failed to terminate Tardis tasks: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/tardis/src/data.rs","lineNumber":518,"sourceCode":"\n    fn unsubscribe_funding_rates(&mut self, _cmd: &UnsubscribeFundingRates) -> anyhow::Result<()> {\n        Ok(())\n    }\n\n    async fn connect(&mut self) -> anyhow::Result<()> {\n        if self.is_connected() && self.tasks.is_open() {\n            return Ok(());\n        }\n\n        if self.config.options.is_empty() && self.config.stream_options.is_empty() {\n            anyhow::bail!(\"Either replay `options` or `stream_options` must be provided\");\n        }\n\n        if !self.tasks.is_open() {\n            self.tasks\n                .finish_shutdown(Duration::from_secs(1), Duration::from_secs(2))\n                .await\n                .map_err(|e| anyhow::anyhow!(\"Failed to terminate Tardis tasks: {e}\"))?;\n            self.tasks\n                .start_generation()\n                .map_err(|e| anyhow::anyhow!(\"Failed to start Tardis task generation: {e}\"))?;\n            self.cancellation_token = self.tasks.cancellation_token();\n        }\n\n        let is_stream_mode = self.is_stream_mode();\n        let book_snapshot_output = self.config.book_snapshot_output.clone();\n        let extract_bbo_as_quotes = self.config.extract_bbo_as_quotes;\n\n        let http_client = TardisHttpClient::new(\n            self.config\n                .api_key\n                .as_ref()\n                .map(|value| value.expose_secret()),\n            None,\n            None,\n            self.config.normalize_symbols,","sourceCodeStart":500,"sourceCodeEnd":536,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/tardis/src/data.rs#L500-L536","documentation":"Raised in connect when finish_shutdown on the Tardis task set fails (does not complete within the 1s/2s grace windows) while preparing for a (re)connection. The prior generation of stream tasks could not be terminated cleanly, so connect aborts.","triggerScenarios":"Calling connect while existing WebSocket tasks ignore the cancellation token and keep running past the finish_shutdown timeouts.","commonSituations":"WebSocket read loop blocked on a stalled Tardis Machine connection without honoring cancellation; very slow network teardown; tasks awaiting a long I/O future between cancellation checks.","solutions":["Ensure the WS task loop selects on the cancellation token so it exits promptly.","Increase the finish_shutdown grace durations if tasks legitimately need longer to stop.","Check network conditions toward the Tardis Machine; a hung socket can stall graceful shutdown.","Drop/recreate the client if the task set is wedged."],"exampleFix":"// before\n.map_err(|e| anyhow::anyhow!(\"Failed to terminate Tardis tasks: {e}\"))?;\n// after: make the ws loop cancellation-responsive\n// tokio::select! { _ = cancellation_token.cancelled() => break, msg = ws.next() => ... }","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"match connect().await {\n    Err(e) if e.to_string().contains(\"Failed to terminate Tardis tasks\") => {\n        log::warn!(\"previous tasks wedged; restarting client\");\n        client = TardisDataClient::new(config)?; // recreate instead of retrying in-place\n        client.connect().await?;\n    }\n    other => other?,\n}","preventionTips":["Keep WS task loops responsive to the cancellation token (select!).","Set connection read timeouts so stalled sockets can't block shutdown.","Size the finish_shutdown grace windows to your worst-case task teardown."],"tags":["websocket","shutdown","task-management"],"backgroundTag":"request-timeout","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"}