This commit is contained in:
2026-09-04 16:02:51 +07:00
parent 17de4f6376
commit 1d224218df
38 changed files with 894 additions and 2482 deletions
+12 -32
View File
@@ -13,6 +13,7 @@ use signed_core::{Announcement, RepoAddr};
use crate::backend::{Backend, BackendEvent};
use crate::git_store::GitStore;
use crate::local_repos::LocalReposStore;
use crate::refresh::{RefreshGate, RefreshRequest};
use crate::repo_list::RepoListStore;
/// Delay between a refresh request and the actual re-computation.
@@ -83,10 +84,8 @@ pub struct CheckoutsStore {
///
/// A recompute defaults the base the same way.
requested_head: HashMap<RepoAddr, Option<String>>,
refreshing: bool,
refresh_dirty: bool,
/// A refresh is waiting out [`REFRESH_DEBOUNCE`].
debouncing: bool,
/// Refresh coalescing, see [`RefreshGate`].
refresh: RefreshGate,
_subscriptions: Vec<Subscription>,
tasks: Vec<Task<Result<(), Error>>>,
}
@@ -144,9 +143,7 @@ impl CheckoutsStore {
push_requested: HashSet::new(),
push_statuses: Arc::new(HashMap::new()),
requested_head: HashMap::new(),
refreshing: false,
refresh_dirty: false,
debouncing: false,
refresh: RefreshGate::default(),
_subscriptions: subscriptions,
tasks: Vec::new(),
};
@@ -236,22 +233,14 @@ impl CheckoutsStore {
///
/// Requests arriving while a pass runs fold into a follow-up.
pub fn refresh(&mut self, cx: &mut Context<Self>) {
if self.refreshing {
self.refresh_dirty = true;
if self.refresh.request() != RefreshRequest::Schedule {
return;
}
if self.debouncing {
return;
}
self.debouncing = true;
let task = cx.spawn(async move |this, cx| {
cx.background_executor().timer(REFRESH_DEBOUNCE).await;
this.update(cx, |this, cx| {
this.debouncing = false;
this.run_refresh(cx);
})
this.update(cx, |this, cx| this.run_refresh(cx))
});
self.tasks.push(task);
@@ -259,7 +248,7 @@ impl CheckoutsStore {
/// One resolve and apply cycle, the debounced entry point.
fn run_refresh(&mut self, cx: &mut Context<Self>) {
self.refreshing = true;
self.refresh.begin();
// Inputs snapshot, all cheap shared reads.
let records = {
@@ -362,7 +351,7 @@ impl CheckoutsStore {
Err(_) => {
// Git reads are best-effort, keep the last results.
return this.update(cx, |this, _cx| {
this.refreshing = false;
this.refresh.abort();
});
}
};
@@ -373,13 +362,7 @@ impl CheckoutsStore {
this.push_statuses = Arc::new(push_statuses);
cx.notify();
this.refreshing = false;
if this.refresh_dirty {
this.refresh_dirty = false;
true
} else {
false
}
this.refresh.finish()
})?;
if again {
@@ -388,8 +371,8 @@ impl CheckoutsStore {
// Keep the statuses current while any repository panel is open.
this.update(cx, |this, cx| {
if poll && !this.debouncing && !this.refreshing {
this.debouncing = true;
if poll && this.refresh.idle() {
this.refresh.debounce();
// Open panels get the fast cadence.
// Each cycle fetches every watched checkout's remote.
let delay = if this.status_requested.is_empty() {
@@ -400,10 +383,7 @@ impl CheckoutsStore {
let task = cx.spawn(async move |this, cx| {
cx.background_executor().timer(delay).await;
this.update(cx, |this, cx| {
this.debouncing = false;
this.run_refresh(cx);
})
this.update(cx, |this, cx| this.run_refresh(cx))
});
this.tasks.push(task);