Add repl events (#15259)
Release Notes: - N/A --------- Co-authored-by: Kyle Kelley <rgbkrk@gmail.com>
This commit is contained in:
co-authored by
Kyle Kelley
parent
745d2e4d3b
commit
856d9632e4
Generated
+1
@@ -8649,6 +8649,7 @@ dependencies = [
|
|||||||
"anyhow",
|
"anyhow",
|
||||||
"async-dispatcher",
|
"async-dispatcher",
|
||||||
"base64 0.13.1",
|
"base64 0.13.1",
|
||||||
|
"client",
|
||||||
"collections",
|
"collections",
|
||||||
"command_palette_hooks",
|
"command_palette_hooks",
|
||||||
"editor",
|
"editor",
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ use sysinfo::{CpuRefreshKind, Pid, ProcessRefreshKind, RefreshKind, System};
|
|||||||
use telemetry_events::{
|
use telemetry_events::{
|
||||||
ActionEvent, AppEvent, AssistantEvent, AssistantKind, CallEvent, CpuEvent, EditEvent,
|
ActionEvent, AppEvent, AssistantEvent, AssistantKind, CallEvent, CpuEvent, EditEvent,
|
||||||
EditorEvent, Event, EventRequestBody, EventWrapper, ExtensionEvent, InlineCompletionEvent,
|
EditorEvent, Event, EventRequestBody, EventWrapper, ExtensionEvent, InlineCompletionEvent,
|
||||||
MemoryEvent, SettingEvent,
|
MemoryEvent, ReplEvent, SettingEvent,
|
||||||
};
|
};
|
||||||
use tempfile::NamedTempFile;
|
use tempfile::NamedTempFile;
|
||||||
#[cfg(not(debug_assertions))]
|
#[cfg(not(debug_assertions))]
|
||||||
@@ -531,6 +531,21 @@ impl Telemetry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn report_repl_event(
|
||||||
|
self: &Arc<Self>,
|
||||||
|
kernel_language: String,
|
||||||
|
kernel_status: String,
|
||||||
|
repl_session_id: String,
|
||||||
|
) {
|
||||||
|
let event = Event::Repl(ReplEvent {
|
||||||
|
kernel_language,
|
||||||
|
kernel_status,
|
||||||
|
repl_session_id,
|
||||||
|
});
|
||||||
|
|
||||||
|
self.report_event(event)
|
||||||
|
}
|
||||||
|
|
||||||
fn report_event(self: &Arc<Self>, event: Event) {
|
fn report_event(self: &Arc<Self>, event: Event) {
|
||||||
let mut state = self.state.lock();
|
let mut state = self.state.lock();
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ use sha2::{Digest, Sha256};
|
|||||||
use std::sync::{Arc, OnceLock};
|
use std::sync::{Arc, OnceLock};
|
||||||
use telemetry_events::{
|
use telemetry_events::{
|
||||||
ActionEvent, AppEvent, AssistantEvent, CallEvent, CpuEvent, EditEvent, EditorEvent, Event,
|
ActionEvent, AppEvent, AssistantEvent, CallEvent, CpuEvent, EditEvent, EditorEvent, Event,
|
||||||
EventRequestBody, EventWrapper, ExtensionEvent, InlineCompletionEvent, MemoryEvent,
|
EventRequestBody, EventWrapper, ExtensionEvent, InlineCompletionEvent, MemoryEvent, ReplEvent,
|
||||||
SettingEvent,
|
SettingEvent,
|
||||||
};
|
};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
@@ -518,6 +518,13 @@ pub async fn post_events(
|
|||||||
checksum_matched,
|
checksum_matched,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
Event::Repl(event) => to_upload.repl_events.push(ReplEventRow::from_event(
|
||||||
|
event.clone(),
|
||||||
|
&wrapper,
|
||||||
|
&request_body,
|
||||||
|
first_event_at,
|
||||||
|
checksum_matched,
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -542,6 +549,7 @@ struct ToUpload {
|
|||||||
extension_events: Vec<ExtensionEventRow>,
|
extension_events: Vec<ExtensionEventRow>,
|
||||||
edit_events: Vec<EditEventRow>,
|
edit_events: Vec<EditEventRow>,
|
||||||
action_events: Vec<ActionEventRow>,
|
action_events: Vec<ActionEventRow>,
|
||||||
|
repl_events: Vec<ReplEventRow>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToUpload {
|
impl ToUpload {
|
||||||
@@ -617,6 +625,11 @@ impl ToUpload {
|
|||||||
.await
|
.await
|
||||||
.with_context(|| format!("failed to upload to table '{ACTION_EVENTS_TABLE}'"))?;
|
.with_context(|| format!("failed to upload to table '{ACTION_EVENTS_TABLE}'"))?;
|
||||||
|
|
||||||
|
const REPL_EVENTS_TABLE: &str = "repl_events";
|
||||||
|
Self::upload_to_table(REPL_EVENTS_TABLE, &self.repl_events, clickhouse_client)
|
||||||
|
.await
|
||||||
|
.with_context(|| format!("failed to upload to table '{REPL_EVENTS_TABLE}'"))?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -625,22 +638,24 @@ impl ToUpload {
|
|||||||
rows: &[T],
|
rows: &[T],
|
||||||
clickhouse_client: &clickhouse::Client,
|
clickhouse_client: &clickhouse::Client,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
if !rows.is_empty() {
|
if rows.is_empty() {
|
||||||
let mut insert = clickhouse_client.insert(table)?;
|
return Ok(());
|
||||||
|
|
||||||
for event in rows {
|
|
||||||
insert.write(event).await?;
|
|
||||||
}
|
|
||||||
|
|
||||||
insert.end().await?;
|
|
||||||
|
|
||||||
let event_count = rows.len();
|
|
||||||
log::info!(
|
|
||||||
"wrote {event_count} {event_specifier} to '{table}'",
|
|
||||||
event_specifier = if event_count == 1 { "event" } else { "events" }
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut insert = clickhouse_client.insert(table)?;
|
||||||
|
|
||||||
|
for event in rows {
|
||||||
|
insert.write(event).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
insert.end().await?;
|
||||||
|
|
||||||
|
let event_count = rows.len();
|
||||||
|
log::info!(
|
||||||
|
"wrote {event_count} {event_specifier} to '{table}'",
|
||||||
|
event_specifier = if event_count == 1 { "event" } else { "events" }
|
||||||
|
);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1189,6 +1204,62 @@ impl ExtensionEventRow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Debug, clickhouse::Row)]
|
||||||
|
pub struct ReplEventRow {
|
||||||
|
// AppInfoBase
|
||||||
|
app_version: String,
|
||||||
|
major: Option<i32>,
|
||||||
|
minor: Option<i32>,
|
||||||
|
patch: Option<i32>,
|
||||||
|
checksum_matched: bool,
|
||||||
|
release_channel: String,
|
||||||
|
os_name: String,
|
||||||
|
os_version: String,
|
||||||
|
|
||||||
|
// ClientEventBase
|
||||||
|
installation_id: Option<String>,
|
||||||
|
session_id: Option<String>,
|
||||||
|
is_staff: Option<bool>,
|
||||||
|
time: i64,
|
||||||
|
|
||||||
|
// ReplEventRow
|
||||||
|
kernel_language: String,
|
||||||
|
kernel_status: String,
|
||||||
|
repl_session_id: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ReplEventRow {
|
||||||
|
fn from_event(
|
||||||
|
event: ReplEvent,
|
||||||
|
wrapper: &EventWrapper,
|
||||||
|
body: &EventRequestBody,
|
||||||
|
first_event_at: chrono::DateTime<chrono::Utc>,
|
||||||
|
checksum_matched: bool,
|
||||||
|
) -> Self {
|
||||||
|
let semver = body.semver();
|
||||||
|
let time =
|
||||||
|
first_event_at + chrono::Duration::milliseconds(wrapper.milliseconds_since_first_event);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
app_version: body.app_version.clone(),
|
||||||
|
major: semver.map(|v| v.major() as i32),
|
||||||
|
minor: semver.map(|v| v.minor() as i32),
|
||||||
|
patch: semver.map(|v| v.patch() as i32),
|
||||||
|
checksum_matched,
|
||||||
|
release_channel: body.release_channel.clone().unwrap_or_default(),
|
||||||
|
os_name: body.os_name.clone(),
|
||||||
|
os_version: body.os_version.clone().unwrap_or_default(),
|
||||||
|
installation_id: body.installation_id.clone(),
|
||||||
|
session_id: body.session_id.clone(),
|
||||||
|
is_staff: body.is_staff,
|
||||||
|
time: time.timestamp_millis(),
|
||||||
|
kernel_language: event.kernel_language,
|
||||||
|
kernel_status: event.kernel_status,
|
||||||
|
repl_session_id: event.repl_session_id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Debug, clickhouse::Row)]
|
#[derive(Serialize, Debug, clickhouse::Row)]
|
||||||
pub struct EditEventRow {
|
pub struct EditEventRow {
|
||||||
// AppInfoBase
|
// AppInfoBase
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ alacritty_terminal.workspace = true
|
|||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
async-dispatcher.workspace = true
|
async-dispatcher.workspace = true
|
||||||
base64.workspace = true
|
base64.workspace = true
|
||||||
|
client.workspace = true
|
||||||
collections.workspace = true
|
collections.workspace = true
|
||||||
command_palette_hooks.workspace = true
|
command_palette_hooks.workspace = true
|
||||||
editor.workspace = true
|
editor.workspace = true
|
||||||
|
|||||||
@@ -24,13 +24,14 @@ pub use crate::repl_sessions_ui::{
|
|||||||
};
|
};
|
||||||
use crate::repl_store::ReplStore;
|
use crate::repl_store::ReplStore;
|
||||||
pub use crate::session::Session;
|
pub use crate::session::Session;
|
||||||
|
use client::telemetry::Telemetry;
|
||||||
|
|
||||||
pub fn init(fs: Arc<dyn Fs>, cx: &mut AppContext) {
|
pub fn init(fs: Arc<dyn Fs>, telemetry: Arc<Telemetry>, cx: &mut AppContext) {
|
||||||
set_dispatcher(zed_dispatcher(cx));
|
set_dispatcher(zed_dispatcher(cx));
|
||||||
JupyterSettings::register(cx);
|
JupyterSettings::register(cx);
|
||||||
::editor::init_settings(cx);
|
::editor::init_settings(cx);
|
||||||
repl_sessions_ui::init(cx);
|
repl_sessions_ui::init(cx);
|
||||||
ReplStore::init(fs, cx);
|
ReplStore::init(fs, telemetry, cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn zed_dispatcher(cx: &mut AppContext) -> impl Dispatcher {
|
fn zed_dispatcher(cx: &mut AppContext) -> impl Dispatcher {
|
||||||
|
|||||||
@@ -42,12 +42,15 @@ pub fn run(editor: WeakView<Editor>, cx: &mut WindowContext) -> Result<()> {
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
let fs = store.read(cx).fs().clone();
|
let fs = store.read(cx).fs().clone();
|
||||||
|
let telemetry = store.read(cx).telemetry().clone();
|
||||||
|
|
||||||
let session = if let Some(session) = store.read(cx).get_session(editor.entity_id()).cloned()
|
let session = if let Some(session) = store.read(cx).get_session(editor.entity_id()).cloned()
|
||||||
{
|
{
|
||||||
session
|
session
|
||||||
} else {
|
} else {
|
||||||
let weak_editor = editor.downgrade();
|
let weak_editor = editor.downgrade();
|
||||||
let session = cx.new_view(|cx| Session::new(weak_editor, fs, kernel_specification, cx));
|
let session = cx
|
||||||
|
.new_view(|cx| Session::new(weak_editor, fs, telemetry, kernel_specification, cx));
|
||||||
|
|
||||||
editor.update(cx, |_editor, cx| {
|
editor.update(cx, |_editor, cx| {
|
||||||
cx.notify();
|
cx.notify();
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use client::telemetry::Telemetry;
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
use command_palette_hooks::CommandPaletteFilter;
|
use command_palette_hooks::CommandPaletteFilter;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
@@ -22,14 +23,15 @@ pub struct ReplStore {
|
|||||||
enabled: bool,
|
enabled: bool,
|
||||||
sessions: HashMap<EntityId, View<Session>>,
|
sessions: HashMap<EntityId, View<Session>>,
|
||||||
kernel_specifications: Vec<KernelSpecification>,
|
kernel_specifications: Vec<KernelSpecification>,
|
||||||
|
telemetry: Arc<Telemetry>,
|
||||||
_subscriptions: Vec<Subscription>,
|
_subscriptions: Vec<Subscription>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReplStore {
|
impl ReplStore {
|
||||||
const NAMESPACE: &'static str = "repl";
|
const NAMESPACE: &'static str = "repl";
|
||||||
|
|
||||||
pub(crate) fn init(fs: Arc<dyn Fs>, cx: &mut AppContext) {
|
pub(crate) fn init(fs: Arc<dyn Fs>, telemetry: Arc<Telemetry>, cx: &mut AppContext) {
|
||||||
let store = cx.new_model(move |cx| Self::new(fs, cx));
|
let store = cx.new_model(move |cx| Self::new(fs, telemetry, cx));
|
||||||
|
|
||||||
store
|
store
|
||||||
.update(cx, |store, cx| store.refresh_kernelspecs(cx))
|
.update(cx, |store, cx| store.refresh_kernelspecs(cx))
|
||||||
@@ -42,13 +44,14 @@ impl ReplStore {
|
|||||||
cx.global::<GlobalReplStore>().0.clone()
|
cx.global::<GlobalReplStore>().0.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(fs: Arc<dyn Fs>, cx: &mut ModelContext<Self>) -> Self {
|
pub fn new(fs: Arc<dyn Fs>, telemetry: Arc<Telemetry>, cx: &mut ModelContext<Self>) -> Self {
|
||||||
let subscriptions = vec![cx.observe_global::<SettingsStore>(move |this, cx| {
|
let subscriptions = vec![cx.observe_global::<SettingsStore>(move |this, cx| {
|
||||||
this.set_enabled(JupyterSettings::enabled(cx), cx);
|
this.set_enabled(JupyterSettings::enabled(cx), cx);
|
||||||
})];
|
})];
|
||||||
|
|
||||||
let this = Self {
|
let this = Self {
|
||||||
fs,
|
fs,
|
||||||
|
telemetry,
|
||||||
enabled: JupyterSettings::enabled(cx),
|
enabled: JupyterSettings::enabled(cx),
|
||||||
sessions: HashMap::default(),
|
sessions: HashMap::default(),
|
||||||
kernel_specifications: Vec::new(),
|
kernel_specifications: Vec::new(),
|
||||||
@@ -62,6 +65,10 @@ impl ReplStore {
|
|||||||
&self.fs
|
&self.fs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn telemetry(&self) -> &Arc<Telemetry> {
|
||||||
|
&self.telemetry
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_enabled(&self) -> bool {
|
pub fn is_enabled(&self) -> bool {
|
||||||
self.enabled
|
self.enabled
|
||||||
}
|
}
|
||||||
|
|||||||
+51
-13
@@ -1,8 +1,10 @@
|
|||||||
use crate::components::KernelListItem;
|
use crate::components::KernelListItem;
|
||||||
|
use crate::KernelStatus;
|
||||||
use crate::{
|
use crate::{
|
||||||
kernels::{Kernel, KernelSpecification, RunningKernel},
|
kernels::{Kernel, KernelSpecification, RunningKernel},
|
||||||
outputs::{ExecutionStatus, ExecutionView, LineHeight as _},
|
outputs::{ExecutionStatus, ExecutionView, LineHeight as _},
|
||||||
};
|
};
|
||||||
|
use client::telemetry::Telemetry;
|
||||||
use collections::{HashMap, HashSet};
|
use collections::{HashMap, HashSet};
|
||||||
use editor::{
|
use editor::{
|
||||||
display_map::{
|
display_map::{
|
||||||
@@ -34,6 +36,7 @@ pub struct Session {
|
|||||||
blocks: HashMap<String, EditorBlock>,
|
blocks: HashMap<String, EditorBlock>,
|
||||||
messaging_task: Task<()>,
|
messaging_task: Task<()>,
|
||||||
pub kernel_specification: KernelSpecification,
|
pub kernel_specification: KernelSpecification,
|
||||||
|
telemetry: Arc<Telemetry>,
|
||||||
_buffer_subscription: Subscription,
|
_buffer_subscription: Subscription,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,9 +208,18 @@ impl Session {
|
|||||||
pub fn new(
|
pub fn new(
|
||||||
editor: WeakView<Editor>,
|
editor: WeakView<Editor>,
|
||||||
fs: Arc<dyn Fs>,
|
fs: Arc<dyn Fs>,
|
||||||
|
telemetry: Arc<Telemetry>,
|
||||||
kernel_specification: KernelSpecification,
|
kernel_specification: KernelSpecification,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
let kernel_language = kernel_specification.kernelspec.language.clone();
|
||||||
|
|
||||||
|
telemetry.report_repl_event(
|
||||||
|
kernel_language.clone(),
|
||||||
|
KernelStatus::Starting.to_string(),
|
||||||
|
cx.entity_id().to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
let entity_id = editor.entity_id();
|
let entity_id = editor.entity_id();
|
||||||
let working_directory = editor
|
let working_directory = editor
|
||||||
.upgrade()
|
.upgrade()
|
||||||
@@ -227,11 +239,11 @@ impl Session {
|
|||||||
|
|
||||||
match kernel {
|
match kernel {
|
||||||
Ok((mut kernel, mut messages_rx)) => {
|
Ok((mut kernel, mut messages_rx)) => {
|
||||||
this.update(&mut cx, |this, cx| {
|
this.update(&mut cx, |session, cx| {
|
||||||
// At this point we can create a new kind of kernel that has the process and our long running background tasks
|
// At this point we can create a new kind of kernel that has the process and our long running background tasks
|
||||||
|
|
||||||
let status = kernel.process.status();
|
let status = kernel.process.status();
|
||||||
this.kernel = Kernel::RunningKernel(kernel);
|
session.kernel(Kernel::RunningKernel(kernel), cx);
|
||||||
|
|
||||||
cx.spawn(|session, mut cx| async move {
|
cx.spawn(|session, mut cx| async move {
|
||||||
let error_message = match status.await {
|
let error_message = match status.await {
|
||||||
@@ -252,8 +264,10 @@ impl Session {
|
|||||||
|
|
||||||
session
|
session
|
||||||
.update(&mut cx, |session, cx| {
|
.update(&mut cx, |session, cx| {
|
||||||
session.kernel =
|
session.kernel(
|
||||||
Kernel::ErroredLaunch(error_message.clone());
|
Kernel::ErroredLaunch(error_message.clone()),
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
|
||||||
session.blocks.values().for_each(|block| {
|
session.blocks.values().for_each(|block| {
|
||||||
block.execution_view.update(
|
block.execution_view.update(
|
||||||
@@ -282,7 +296,7 @@ impl Session {
|
|||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
|
|
||||||
this.messaging_task = cx.spawn(|session, mut cx| async move {
|
session.messaging_task = cx.spawn(|session, mut cx| async move {
|
||||||
while let Some(message) = messages_rx.next().await {
|
while let Some(message) = messages_rx.next().await {
|
||||||
session
|
session
|
||||||
.update(&mut cx, |session, cx| {
|
.update(&mut cx, |session, cx| {
|
||||||
@@ -295,8 +309,8 @@ impl Session {
|
|||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
this.update(&mut cx, |this, _cx| {
|
this.update(&mut cx, |session, cx| {
|
||||||
this.kernel = Kernel::ErroredLaunch(err.to_string());
|
session.kernel(Kernel::ErroredLaunch(err.to_string()), cx);
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
@@ -319,6 +333,7 @@ impl Session {
|
|||||||
blocks: HashMap::default(),
|
blocks: HashMap::default(),
|
||||||
kernel_specification,
|
kernel_specification,
|
||||||
_buffer_subscription: subscription,
|
_buffer_subscription: subscription,
|
||||||
|
telemetry,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -474,8 +489,8 @@ impl Session {
|
|||||||
|
|
||||||
cx.spawn(|this, mut cx| async move {
|
cx.spawn(|this, mut cx| async move {
|
||||||
task.await;
|
task.await;
|
||||||
this.update(&mut cx, |this, cx| {
|
this.update(&mut cx, |session, cx| {
|
||||||
this.send(message, cx).ok();
|
session.send(message, cx).ok();
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
})
|
})
|
||||||
@@ -501,6 +516,13 @@ impl Session {
|
|||||||
match &message.content {
|
match &message.content {
|
||||||
JupyterMessageContent::Status(status) => {
|
JupyterMessageContent::Status(status) => {
|
||||||
self.kernel.set_execution_state(&status.execution_state);
|
self.kernel.set_execution_state(&status.execution_state);
|
||||||
|
|
||||||
|
self.telemetry.report_repl_event(
|
||||||
|
self.kernel_specification.kernelspec.language.clone(),
|
||||||
|
KernelStatus::from(&self.kernel).to_string(),
|
||||||
|
cx.entity_id().to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
JupyterMessageContent::KernelInfoReply(reply) => {
|
JupyterMessageContent::KernelInfoReply(reply) => {
|
||||||
@@ -528,6 +550,23 @@ impl Session {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn kernel(&mut self, kernel: Kernel, cx: &mut ViewContext<Self>) {
|
||||||
|
if let Kernel::Shutdown = kernel {
|
||||||
|
cx.emit(SessionEvent::Shutdown(self.editor.clone()));
|
||||||
|
}
|
||||||
|
|
||||||
|
let kernel_status = KernelStatus::from(&kernel).to_string();
|
||||||
|
let kernel_language = self.kernel_specification.kernelspec.language.clone();
|
||||||
|
|
||||||
|
self.telemetry.report_repl_event(
|
||||||
|
kernel_language,
|
||||||
|
kernel_status,
|
||||||
|
cx.entity_id().to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
|
self.kernel = kernel;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn shutdown(&mut self, cx: &mut ViewContext<Self>) {
|
pub fn shutdown(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
let kernel = std::mem::replace(&mut self.kernel, Kernel::ShuttingDown);
|
let kernel = std::mem::replace(&mut self.kernel, Kernel::ShuttingDown);
|
||||||
|
|
||||||
@@ -544,10 +583,9 @@ impl Session {
|
|||||||
|
|
||||||
kernel.process.kill().ok();
|
kernel.process.kill().ok();
|
||||||
|
|
||||||
this.update(&mut cx, |this, cx| {
|
this.update(&mut cx, |session, cx| {
|
||||||
cx.emit(SessionEvent::Shutdown(this.editor.clone()));
|
session.clear_outputs(cx);
|
||||||
this.clear_outputs(cx);
|
session.kernel(Kernel::Shutdown, cx);
|
||||||
this.kernel = Kernel::Shutdown;
|
|
||||||
cx.notify();
|
cx.notify();
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ pub enum Event {
|
|||||||
Extension(ExtensionEvent),
|
Extension(ExtensionEvent),
|
||||||
Edit(EditEvent),
|
Edit(EditEvent),
|
||||||
Action(ActionEvent),
|
Action(ActionEvent),
|
||||||
|
Repl(ReplEvent),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
@@ -148,6 +149,13 @@ pub struct AppEvent {
|
|||||||
pub operation: String,
|
pub operation: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct ReplEvent {
|
||||||
|
pub kernel_language: String,
|
||||||
|
pub kernel_status: String,
|
||||||
|
pub repl_session_id: String,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct BacktraceFrame {
|
pub struct BacktraceFrame {
|
||||||
pub ip: usize,
|
pub ip: usize,
|
||||||
|
|||||||
@@ -169,7 +169,11 @@ fn init_common(app_state: Arc<AppState>, cx: &mut AppContext) {
|
|||||||
supermaven::init(app_state.client.clone(), cx);
|
supermaven::init(app_state.client.clone(), cx);
|
||||||
inline_completion_registry::init(app_state.client.telemetry().clone(), cx);
|
inline_completion_registry::init(app_state.client.telemetry().clone(), cx);
|
||||||
assistant::init(app_state.fs.clone(), app_state.client.clone(), cx);
|
assistant::init(app_state.fs.clone(), app_state.client.clone(), cx);
|
||||||
repl::init(app_state.fs.clone(), cx);
|
repl::init(
|
||||||
|
app_state.fs.clone(),
|
||||||
|
app_state.client.telemetry().clone(),
|
||||||
|
cx,
|
||||||
|
);
|
||||||
extension::init(
|
extension::init(
|
||||||
app_state.fs.clone(),
|
app_state.fs.clone(),
|
||||||
app_state.client.clone(),
|
app_state.client.clone(),
|
||||||
|
|||||||
@@ -3460,7 +3460,11 @@ mod tests {
|
|||||||
terminal_view::init(cx);
|
terminal_view::init(cx);
|
||||||
language_model::init(app_state.client.clone(), cx);
|
language_model::init(app_state.client.clone(), cx);
|
||||||
assistant::init(app_state.fs.clone(), app_state.client.clone(), cx);
|
assistant::init(app_state.fs.clone(), app_state.client.clone(), cx);
|
||||||
repl::init(app_state.fs.clone(), cx);
|
repl::init(
|
||||||
|
app_state.fs.clone(),
|
||||||
|
app_state.client.telemetry().clone(),
|
||||||
|
cx,
|
||||||
|
);
|
||||||
tasks_ui::init(cx);
|
tasks_ui::init(cx);
|
||||||
initialize_workspace(app_state.clone(), cx);
|
initialize_workspace(app_state.clone(), cx);
|
||||||
app_state
|
app_state
|
||||||
|
|||||||
Reference in New Issue
Block a user