zed/crates/repl/src/repl.rs
Yara 🏳️‍⚧️ 39f7849a0f
Log worst hanging tasks and actions (#57835)
We have a lot of long blocking tasks on both the foreground and
background, this is a start of getting some insight into those.

We will now log tasks running longer then 100ms on the foreground or
background. Hanging actions will also be logged including their name. We
simultaneously collect statistics on task and action performance and
send those to telemetry. This includes quantiles and averages for each
hanging task.

Finally this adds tree dev actions: 
- hang action
- hang foreground
- hang background

These cause a hang to check if hang reporting is working and in the
future telemetry.

Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Closes #ISSUE

Release Notes:

- Added logging and telemetry of tasks and actions with performance
issues
2026-06-02 12:03:05 +00:00

75 lines
2.5 KiB
Rust

pub mod components;
mod jupyter_settings;
pub mod kernels;
pub mod notebook;
mod outputs;
mod repl_editor;
mod repl_sessions_ui;
mod repl_settings;
mod repl_store;
mod session;
use std::{sync::Arc, time::Duration};
use async_dispatcher::{Dispatcher, Runnable, set_dispatcher};
use gpui::{App, PlatformDispatcher, Priority, RunnableMeta};
use project::Fs;
pub use runtimelib::ExecutionState;
pub use crate::jupyter_settings::JupyterSettings;
pub use crate::kernels::{Kernel, KernelSpecification, KernelStatus, PythonEnvKernelSpecification};
pub use crate::repl_editor::*;
pub use crate::repl_sessions_ui::{
ClearCurrentOutput, ClearOutputs, Interrupt, ReplSessionsPage, Restart, Run, Sessions, Shutdown,
};
pub use crate::repl_settings::ReplSettings;
pub use crate::repl_store::ReplStore;
pub use crate::session::Session;
pub const KERNEL_DOCS_URL: &str = "https://zed.dev/docs/repl#changing-kernels";
pub fn init(fs: Arc<dyn Fs>, cx: &mut App) {
set_dispatcher(zed_dispatcher(cx));
repl_sessions_ui::init(cx);
ReplStore::init(fs, cx);
}
fn zed_dispatcher(cx: &mut App) -> impl Dispatcher {
struct ZedDispatcher {
dispatcher: Arc<dyn PlatformDispatcher>,
}
// PlatformDispatcher is _super_ close to the same interface we put in
// async-dispatcher, except for the task label in dispatch. Later we should
// just make that consistent so we have this dispatcher ready to go for
// other crates in Zed.
impl Dispatcher for ZedDispatcher {
#[track_caller]
fn dispatch(&self, runnable: Runnable) {
let (wrapper, task) = async_task::Builder::new()
.metadata(RunnableMeta::new_with_callers_location())
.spawn(|_| async move { runnable.run() }, {
let dispatcher = self.dispatcher.clone();
move |r| dispatcher.dispatch(r, Priority::default())
});
wrapper.schedule();
task.detach();
}
#[track_caller]
fn dispatch_after(&self, duration: Duration, runnable: Runnable) {
let (wrapper, task) = async_task::Builder::new()
.metadata(RunnableMeta::new_with_callers_location())
.spawn(|_| async move { runnable.run() }, {
let dispatcher = self.dispatcher.clone();
move |r| dispatcher.dispatch_after(duration, r)
});
wrapper.schedule();
task.detach();
}
}
ZedDispatcher {
dispatcher: cx.background_executor().dispatcher().clone(),
}
}