fix leak tasks

This commit is contained in:
2026-09-27 09:24:41 +07:00
parent 0ee67d93b6
commit 8ea320cd6f
4 changed files with 33 additions and 32 deletions
+17 -23
View File
@@ -87,7 +87,7 @@ pub struct RepoStore {
/// ///
/// Avoids re-running the maintainer Auto sync on every refresh. /// Avoids re-running the maintainer Auto sync on every refresh.
synced_maintainers: HashSet<PublicKey>, synced_maintainers: HashSet<PublicKey>,
/// In-flight refresh tasks. /// In-flight tasks, cancelled when the store drops.
tasks: Vec<Task<Result<(), Error>>>, tasks: Vec<Task<Result<(), Error>>>,
/// Backend subscription of an announced repository. `None` while local-only. /// Backend subscription of an announced repository. `None` while local-only.
_subscription: Option<Subscription>, _subscription: Option<Subscription>,
@@ -770,9 +770,9 @@ impl RepoStore {
.collect() .collect()
}; };
cx.spawn(async move |this, cx| { let task: Task<Result<(), Error>> = cx.spawn(async move |this, cx| {
// The PR references the root patch event. // The PR references the root patch,
// Viewers can then find the patch without carrying it inline. // viewers can then find the patch without carrying it inline.
let root_patch = match publish_patch_series( let root_patch = match publish_patch_series(
&this, &this,
cx, cx,
@@ -838,24 +838,17 @@ impl RepoStore {
}; };
let builder = this.update(cx, |this, _cx| { let builder = this.update(cx, |this, _cx| {
// NIP-34 PRs carry at least one clone URL.
// The tip commit is downloadable from it.
// The author's `/prs/` URLs come first.
// They are author-controlled and most likely alive.
// The announced mirrors follow.
// The list is fixed before signing.
// The pushed ref name embeds the event id.
// Every candidate URL is listed up front.
// Dead URLs are inert, the linked patch stays the source of truth.
let prs_urls: Vec<Url> = author_targets let prs_urls: Vec<Url> = author_targets
.iter() .iter()
.filter_map(|(url, _)| Url::parse(url).ok()) .filter_map(|(url, _)| Url::parse(url).ok())
.collect(); .collect();
let base_clone = this let base_clone = this
.announcement .announcement
.as_ref() .as_ref()
.map(|a| a.clone.clone()) .map(|a| a.clone.clone())
.unwrap_or_default(); .unwrap_or_default();
let clone = pr_clone_urls(prs_urls, base_clone); let clone = pr_clone_urls(prs_urls, base_clone);
let builder = GitPullRequest { let builder = GitPullRequest {
@@ -880,8 +873,6 @@ impl RepoStore {
})?; })?;
// Sign before publishing. // Sign before publishing.
// The tip is pushed to the grasp servers under `refs/nostr/<event-id>`.
// Nak's convention, readers fetch that ref for the commit behind the `c` tag.
let event = cx let event = cx
.background_spawn({ .background_spawn({
let signer = signer.clone(); let signer = signer.clone();
@@ -892,20 +883,22 @@ impl RepoStore {
if let Some(path) = push_from.as_ref() { if let Some(path) = push_from.as_ref() {
let tip = current_commit.to_string(); let tip = current_commit.to_string();
let reference = format!("refs/nostr/{}", event.id.to_hex()); let reference = format!("refs/nostr/{}", event.id.to_hex());
let (pushed, failures) = cx let (pushed, failures) = cx
.background_spawn({ .background_spawn({
let path = path.clone(); let path = path.clone();
let tip = tip.clone(); let tip = tip.clone();
let reference = reference.clone(); let reference = reference.clone();
// Author servers first, then the announced base grasp servers. // Author servers first, then the announced base grasp servers.
// The extra targets are best-effort redundancy.
let targets: Vec<(String, String)> = author_targets let targets: Vec<(String, String)> = author_targets
.into_iter() .into_iter()
.chain(base_targets) .chain(base_targets)
.collect(); .collect();
async move { async move {
let mut failures = Vec::new(); let mut failures = Vec::new();
let mut pushed = 0; let mut pushed = 0;
for (url, label) in &targets { for (url, label) in &targets {
match signed_git::push_commit_ref( match signed_git::push_commit_ref(
&path, url, &tip, &reference, &path, url, &tip, &reference,
@@ -914,6 +907,7 @@ impl RepoStore {
Err(e) => failures.push(format!("{label}: {e}")), Err(e) => failures.push(format!("{label}: {e}")),
} }
} }
(pushed, failures) (pushed, failures)
} }
}) })
@@ -957,8 +951,8 @@ impl RepoStore {
} }
Ok(()) Ok(())
}) });
.detach(); self.tasks.push(task);
} }
/// Generate the patch between `merge_base` and `compare_ref` in `repo_path`, /// Generate the patch between `merge_base` and `compare_ref` in `repo_path`,
@@ -1086,7 +1080,7 @@ impl RepoStore {
.map(|a| a.clone.clone()) .map(|a| a.clone.clone())
.unwrap_or_default(); .unwrap_or_default();
cx.spawn(async move |this, cx| { let task: Task<Result<(), Error>> = cx.spawn(async move |this, cx| {
if let Err(e) = publish_patch_series( if let Err(e) = publish_patch_series(
&this, &this,
cx, cx,
@@ -1145,8 +1139,8 @@ impl RepoStore {
} }
Ok(()) Ok(())
}) });
.detach(); self.tasks.push(task);
} }
/// Set the status of a root event. /// Set the status of a root event.
@@ -1272,7 +1266,7 @@ impl RepoStore {
} }
Ok(()) Ok(())
}); });
task.detach(); self.tasks.push(task);
} }
/// The latest announcement of this repository, /// The latest announcement of this repository,
@@ -1588,7 +1582,7 @@ impl RepoStore {
Ok(()) Ok(())
}); });
task.detach(); self.tasks.push(task);
} }
} }
@@ -303,6 +303,7 @@ pub struct CommitDiffView {
loading: bool, loading: bool,
error: Option<SharedString>, error: Option<SharedString>,
pane: Entity<DiffPane>, pane: Entity<DiffPane>,
tasks: Vec<gpui::Task<Result<(), anyhow::Error>>>,
} }
impl CommitDiffView { impl CommitDiffView {
@@ -336,6 +337,7 @@ impl CommitDiffView {
loading: true, loading: true,
error: None, error: None,
pane, pane,
tasks: Vec::new(),
} }
} }
@@ -383,7 +385,7 @@ impl CommitDiffView {
Ok(()) Ok(())
}); });
task.detach(); self.tasks.push(task);
} }
fn render_header(&self, cx: &mut Context<Self>) -> AnyElement { fn render_header(&self, cx: &mut Context<Self>) -> AnyElement {
@@ -79,8 +79,7 @@ pub struct PullRequestDetailView {
pane: Entity<DiffPane>, pane: Entity<DiffPane>,
commit_item_sizes: Rc<Vec<Size<Pixels>>>, commit_item_sizes: Rc<Vec<Size<Pixels>>>,
commit_scroll_handle: VirtualListScrollHandle, commit_scroll_handle: VirtualListScrollHandle,
/// The dock caches item panels, so without this observer a panel opened tasks: Vec<gpui::Task<Result<(), anyhow::Error>>>,
/// before the store loaded would stay on its placeholder.
_subscription: Subscription, _subscription: Subscription,
} }
@@ -124,6 +123,7 @@ impl PullRequestDetailView {
pane, pane,
commit_item_sizes: Rc::new(Vec::new()), commit_item_sizes: Rc::new(Vec::new()),
commit_scroll_handle: VirtualListScrollHandle::new(), commit_scroll_handle: VirtualListScrollHandle::new(),
tasks: Vec::new(),
_subscription: subscription, _subscription: subscription,
} }
} }
@@ -327,7 +327,7 @@ impl PullRequestDetailView {
Ok(()) Ok(())
}); });
task.detach(); self.tasks.push(task);
} }
/// Open the diff of `commit_id` in the bottom dock of the area. /// Open the diff of `commit_id` in the bottom dock of the area.
@@ -68,6 +68,7 @@ pub struct NewPullRequestView {
pane: Entity<DiffPane>, pane: Entity<DiffPane>,
scroll_handle: VirtualListScrollHandle, scroll_handle: VirtualListScrollHandle,
item_sizes: Rc<Vec<Size<Pixels>>>, item_sizes: Rc<Vec<Size<Pixels>>>,
tasks: Vec<gpui::Task<Result<(), anyhow::Error>>>,
_subscriptions: Vec<Subscription>, _subscriptions: Vec<Subscription>,
} }
@@ -323,6 +324,7 @@ impl NewPullRequestView {
pane, pane,
scroll_handle: VirtualListScrollHandle::new(), scroll_handle: VirtualListScrollHandle::new(),
item_sizes: Rc::new(Vec::new()), item_sizes: Rc::new(Vec::new()),
tasks: Vec::new(),
_subscriptions: subscriptions, _subscriptions: subscriptions,
} }
} }
@@ -390,7 +392,8 @@ impl NewPullRequestView {
Ok(()) Ok(())
}); });
task.detach();
self.tasks.push(task);
} }
/// Branches and the current branch are read off the UI thread, then applied. /// Branches and the current branch are read off the UI thread, then applied.
@@ -419,7 +422,8 @@ impl NewPullRequestView {
Ok(()) Ok(())
}); });
task.detach();
self.tasks.push(task);
} }
fn apply_checkout( fn apply_checkout(
@@ -636,7 +640,8 @@ impl NewPullRequestView {
Ok(()) Ok(())
}); });
task.detach();
self.tasks.push(task);
} }
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
@@ -830,7 +835,7 @@ impl NewPullRequestView {
Ok(()) Ok(())
}); });
task.detach(); self.tasks.push(task);
} }
fn submit(&mut self, window: &mut Window, cx: &mut Context<Self>) { fn submit(&mut self, window: &mut Window, cx: &mut Context<Self>) {
@@ -911,7 +916,7 @@ impl NewPullRequestView {
Ok(()) Ok(())
}); });
task.detach(); self.tasks.push(task);
} }
fn open_commit_diff(&mut self, commit_id: &str, window: &mut Window, cx: &mut Context<Self>) { fn open_commit_diff(&mut self, commit_id: &str, window: &mut Window, cx: &mut Context<Self>) {