diff --git a/crates/repl/src/kernels/mod.rs b/crates/repl/src/kernels/mod.rs index 250628e4f3a219240cc7b68c6c2e3e445896ab40..87ed6ed398fdd4f5ef23d7fef04fca9e000f1e73 100644 --- a/crates/repl/src/kernels/mod.rs +++ b/crates/repl/src/kernels/mod.rs @@ -170,6 +170,7 @@ pub trait RunningKernel: Send + Debug { fn kernel_info(&self) -> Option<&KernelInfoReply>; fn set_kernel_info(&mut self, info: KernelInfoReply); fn force_shutdown(&mut self, window: &mut Window, cx: &mut App) -> Task>; + fn kill(&mut self); } #[derive(Debug, Clone)] diff --git a/crates/repl/src/kernels/native_kernel.rs b/crates/repl/src/kernels/native_kernel.rs index e5eb32d3499a9f7e35fc0104162be3e053d51483..c3fd57557a2c77c8e1c490aae6e7533cd7d161b6 100644 --- a/crates/repl/src/kernels/native_kernel.rs +++ b/crates/repl/src/kernels/native_kernel.rs @@ -370,17 +370,21 @@ impl RunningKernel for NativeRunningKernel { } fn force_shutdown(&mut self, _window: &mut Window, _cx: &mut App) -> Task> { + self.kill(); + Task::ready(Ok(())) + } + + fn kill(&mut self) { self._process_status_task.take(); self.request_tx.close_channel(); - Task::ready(self.process.kill().context("killing the kernel process")) + self.process.kill().ok(); } } impl Drop for NativeRunningKernel { fn drop(&mut self) { std::fs::remove_file(&self.connection_path).ok(); - self.request_tx.close_channel(); - self.process.kill().ok(); + self.kill(); } } diff --git a/crates/repl/src/kernels/remote_kernels.rs b/crates/repl/src/kernels/remote_kernels.rs index 0be657bb8d32954cede08020b7133baf0581689a..165ca387d0ea98fd0402753fa26b39f8b21c33ca 100644 --- a/crates/repl/src/kernels/remote_kernels.rs +++ b/crates/repl/src/kernels/remote_kernels.rs @@ -289,4 +289,8 @@ impl RunningKernel for RemoteRunningKernel { Ok(()) }) } + + fn kill(&mut self) { + self.request_tx.close_channel(); + } } diff --git a/crates/repl/src/repl_store.rs b/crates/repl/src/repl_store.rs index 9d40f059b744424887af0927ad2fbc00c9186a90..abff0bdc3aa20beacbd566c512bbbab1064a1610 100644 --- a/crates/repl/src/repl_store.rs +++ b/crates/repl/src/repl_store.rs @@ -1,3 +1,4 @@ +use std::future::Future; use std::sync::Arc; use anyhow::{Context as _, Result}; @@ -10,7 +11,7 @@ use project::{Fs, Project, WorktreeId}; use settings::{Settings, SettingsStore}; use crate::kernels::{ - list_remote_kernelspecs, local_kernel_specifications, python_env_kernel_specifications, + Kernel, list_remote_kernelspecs, local_kernel_specifications, python_env_kernel_specifications, }; use crate::{JupyterSettings, KernelSpecification, Session}; @@ -47,9 +48,12 @@ impl ReplStore { } pub fn new(fs: Arc, cx: &mut Context) -> Self { - let subscriptions = vec![cx.observe_global::(move |this, cx| { - this.set_enabled(JupyterSettings::enabled(cx), cx); - })]; + let subscriptions = vec![ + cx.observe_global::(move |this, cx| { + this.set_enabled(JupyterSettings::enabled(cx), cx); + }), + cx.on_app_quit(Self::shutdown_all_sessions), + ]; let this = Self { fs, @@ -281,6 +285,23 @@ impl ReplStore { self.sessions.remove(&entity_id); } + fn shutdown_all_sessions( + &mut self, + cx: &mut Context, + ) -> impl Future + use<> { + for session in self.sessions.values() { + session.update(cx, |session, _cx| { + if let Kernel::RunningKernel(mut kernel) = + std::mem::replace(&mut session.kernel, Kernel::Shutdown) + { + kernel.kill(); + } + }); + } + self.sessions.clear(); + futures::future::ready(()) + } + #[cfg(test)] pub fn set_kernel_specs_for_testing( &mut self,