chore: Keep spawn task on it owner. (#1456)

This commit is contained in:
Jason Lee 2025-10-29 19:11:49 +08:00 committed by GitHub
parent d34ea6640a
commit 7036415662
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 29 additions and 21 deletions

View file

@ -8,7 +8,8 @@ use fake::Fake;
use gpui::{
Action, AnyElement, App, AppContext, ClickEvent, Context, Entity, Focusable,
InteractiveElement, IntoElement, ParentElement, Render, SharedString,
StatefulInteractiveElement, Styled, TextAlign, Timer, Window, div, prelude::FluentBuilder as _,
StatefulInteractiveElement, Styled, Subscription, Task, TextAlign, Timer, Window, div,
prelude::FluentBuilder as _,
};
use gpui_component::{
ActiveTheme as _, Selectable, Sizable as _, Size, StyleSized as _, StyledExt,
@ -181,6 +182,8 @@ struct StockTableDelegate {
eof: bool,
visible_rows: Range<usize>,
visible_cols: Range<usize>,
_load_task: Task<()>,
}
impl StockTableDelegate {
@ -260,6 +263,7 @@ impl StockTableDelegate {
eof: false,
visible_cols: Range::default(),
visible_rows: Range::default(),
_load_task: Task::ready(()),
}
}
@ -551,19 +555,18 @@ impl TableDelegate for StockTableDelegate {
fn load_more(&mut self, _: &mut Window, cx: &mut Context<Table<Self>>) {
self.loading = true;
cx.spawn(async move |view, cx| {
self._load_task = cx.spawn(async move |view, cx| {
// Simulate network request, delay 1s to load data.
Timer::after(Duration::from_secs(1)).await;
cx.update(|cx| {
_ = cx.update(|cx| {
let _ = view.update(cx, |view, _| {
view.delegate_mut().stocks.extend(random_stocks(200));
view.delegate_mut().loading = false;
view.delegate_mut().eof = view.delegate().stocks.len() >= 6000;
});
})
})
.detach();
});
});
}
fn visible_rows_changed(
@ -591,6 +594,9 @@ pub struct TableStory {
stripe: bool,
refresh_data: bool,
size: Size,
_subscriptions: Vec<Subscription>,
_load_task: Task<()>,
}
impl super::Story for TableStory {
@ -635,13 +641,13 @@ impl TableStory {
let delegate = StockTableDelegate::new(5000);
let table = cx.new(|cx| Table::new(delegate, window, cx));
cx.subscribe_in(&table, window, Self::on_table_event)
.detach();
cx.subscribe_in(&num_stocks_input, window, Self::on_num_stocks_input_change)
.detach();
let _subscriptions = vec![
cx.subscribe_in(&table, window, Self::on_table_event),
cx.subscribe_in(&num_stocks_input, window, Self::on_num_stocks_input_change),
// Spawn a background to random refresh the list
];
// Spawn a background to random refresh the list
cx.spawn(async move |this, cx| {
let _load_task = cx.spawn(async move |this, cx| {
loop {
Timer::after(time::Duration::from_millis(33)).await;
@ -665,8 +671,7 @@ impl TableStory {
})
.ok();
}
})
.detach();
});
Self {
table,
@ -674,6 +679,8 @@ impl TableStory {
stripe: false,
refresh_data: false,
size: Size::default(),
_subscriptions,
_load_task,
}
}

View file

@ -1,6 +1,6 @@
use std::time::Duration;
use gpui::{px, Context, Pixels, Timer};
use gpui::{px, Context, Pixels, Task, Timer};
static INTERVAL: Duration = Duration::from_millis(500);
static PAUSE_DELAY: Duration = Duration::from_millis(300);
@ -16,6 +16,8 @@ pub(crate) struct BlinkCursor {
visible: bool,
paused: bool,
epoch: usize,
_task: Task<()>,
}
impl BlinkCursor {
@ -24,6 +26,7 @@ impl BlinkCursor {
visible: false,
paused: false,
epoch: 0,
_task: Task::ready(()),
}
}
@ -53,13 +56,12 @@ impl BlinkCursor {
// Schedule the next blink
let epoch = self.next_epoch();
cx.spawn(async move |this, cx| {
self._task = cx.spawn(async move |this, cx| {
Timer::after(INTERVAL).await;
if let Some(this) = this.upgrade() {
this.update(cx, |this, cx| this.blink(epoch, cx)).ok();
}
})
.detach();
});
}
pub fn visible(&self) -> bool {
@ -75,7 +77,7 @@ impl BlinkCursor {
// delay 500ms to start the blinking
let epoch = self.next_epoch();
cx.spawn(async move |this, cx| {
self._task = cx.spawn(async move |this, cx| {
Timer::after(PAUSE_DELAY).await;
if let Some(this) = this.upgrade() {
@ -85,7 +87,6 @@ impl BlinkCursor {
})
.ok();
}
})
.detach();
});
}
}