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.
synced_maintainers: HashSet<PublicKey>,
/// In-flight refresh tasks.
/// In-flight tasks, cancelled when the store drops.
tasks: Vec<Task<Result<(), Error>>>,
/// Backend subscription of an announced repository. `None` while local-only.
_subscription: Option<Subscription>,
@@ -770,9 +770,9 @@ impl RepoStore {
.collect()
};
cx.spawn(async move |this, cx| {
// The PR references the root patch event.
// Viewers can then find the patch without carrying it inline.
let task: Task<Result<(), Error>> = cx.spawn(async move |this, cx| {
// The PR references the root patch,
// viewers can then find the patch without carrying it inline.
let root_patch = match publish_patch_series(
&this,
cx,
@@ -838,24 +838,17 @@ impl RepoStore {
};
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
.iter()
.filter_map(|(url, _)| Url::parse(url).ok())
.collect();
let base_clone = this
.announcement
.as_ref()
.map(|a| a.clone.clone())
.unwrap_or_default();
let clone = pr_clone_urls(prs_urls, base_clone);
let builder = GitPullRequest {
@@ -880,8 +873,6 @@ impl RepoStore {
})?;
// 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
.background_spawn({
let signer = signer.clone();
@@ -892,20 +883,22 @@ impl RepoStore {
if let Some(path) = push_from.as_ref() {
let tip = current_commit.to_string();
let reference = format!("refs/nostr/{}", event.id.to_hex());
let (pushed, failures) = cx
.background_spawn({
let path = path.clone();
let tip = tip.clone();
let reference = reference.clone();
// Author servers first, then the announced base grasp servers.
// The extra targets are best-effort redundancy.
let targets: Vec<(String, String)> = author_targets
.into_iter()
.chain(base_targets)
.collect();
async move {
let mut failures = Vec::new();
let mut pushed = 0;
for (url, label) in &targets {
match signed_git::push_commit_ref(
&path, url, &tip, &reference,
@@ -914,6 +907,7 @@ impl RepoStore {
Err(e) => failures.push(format!("{label}: {e}")),
}
}
(pushed, failures)
}
})
@@ -957,8 +951,8 @@ impl RepoStore {
}
Ok(())
})
.detach();
});
self.tasks.push(task);
}
/// Generate the patch between `merge_base` and `compare_ref` in `repo_path`,
@@ -1086,7 +1080,7 @@ impl RepoStore {
.map(|a| a.clone.clone())
.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(
&this,
cx,
@@ -1145,8 +1139,8 @@ impl RepoStore {
}
Ok(())
})
.detach();
});
self.tasks.push(task);
}
/// Set the status of a root event.
@@ -1272,7 +1266,7 @@ impl RepoStore {
}
Ok(())
});
task.detach();
self.tasks.push(task);
}
/// The latest announcement of this repository,
@@ -1588,7 +1582,7 @@ impl RepoStore {
Ok(())
});
task.detach();
self.tasks.push(task);
}
}