feat(tabs): run the idle archive policy on a periodic sweep
This commit is contained in:
@@ -23,6 +23,11 @@ const NAV_GROUPS: &[NavGroup] = &[
|
|||||||
NavGroup {
|
NavGroup {
|
||||||
label: "GENERAL",
|
label: "GENERAL",
|
||||||
items: &[
|
items: &[
|
||||||
|
NavItem {
|
||||||
|
icon: IconName::Settings2,
|
||||||
|
label: "General",
|
||||||
|
route: "ely://settings/general",
|
||||||
|
},
|
||||||
NavItem {
|
NavItem {
|
||||||
icon: IconName::Palette,
|
icon: IconName::Palette,
|
||||||
label: "Appearance",
|
label: "Appearance",
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ const ARCHIVE_POLICY_OPTIONS: &[ArchivePolicyOption] = &[
|
|||||||
},
|
},
|
||||||
ArchivePolicyOption {
|
ArchivePolicyOption {
|
||||||
label: "Today",
|
label: "Today",
|
||||||
detail: "Archive idle unpinned tabs during daily cleanup.",
|
detail: "Archive unpinned tabs left idle since yesterday.",
|
||||||
policy: ArchivePolicy::IdleDays(0),
|
policy: ArchivePolicy::IdleDays(0),
|
||||||
},
|
},
|
||||||
ArchivePolicyOption {
|
ArchivePolicyOption {
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ mod sync_inbox;
|
|||||||
mod sync_state;
|
mod sync_state;
|
||||||
mod tab_groups;
|
mod tab_groups;
|
||||||
mod tab_lifecycle;
|
mod tab_lifecycle;
|
||||||
|
mod timers;
|
||||||
mod web_surface;
|
mod web_surface;
|
||||||
mod web_surface_cadence;
|
mod web_surface_cadence;
|
||||||
mod web_surface_controller;
|
mod web_surface_controller;
|
||||||
@@ -52,7 +53,7 @@ mod gpui_harness_tests;
|
|||||||
|
|
||||||
use ely_browser_core::{BrowserCore, InitialBrowserConfig};
|
use ely_browser_core::{BrowserCore, InitialBrowserConfig};
|
||||||
use ely_domain::{DEFAULT_TRANSLUCENCY_PCT, ProfileId, SpaceId, TabId};
|
use ely_domain::{DEFAULT_TRANSLUCENCY_PCT, ProfileId, SpaceId, TabId};
|
||||||
use gpui::{AppContext, Context, Entity, FocusHandle, Subscription, Timer, Window};
|
use gpui::{AppContext, Context, Entity, FocusHandle, Subscription, Window};
|
||||||
use gpui_component::input::{InputEvent, InputState};
|
use gpui_component::input::{InputEvent, InputState};
|
||||||
use gpui_component::slider::{SliderEvent, SliderState, SliderValue};
|
use gpui_component::slider::{SliderEvent, SliderState, SliderValue};
|
||||||
|
|
||||||
@@ -313,7 +314,7 @@ impl ElyShell {
|
|||||||
if should_run_initial_sync {
|
if should_run_initial_sync {
|
||||||
shell.trigger_cloud_sync_upload();
|
shell.trigger_cloud_sync_upload();
|
||||||
}
|
}
|
||||||
start_external_web_surface_timer(cx);
|
timers::start(cx);
|
||||||
shell
|
shell
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -477,24 +478,3 @@ impl ElyShell {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_external_web_surface_timer(cx: &mut Context<ElyShell>) {
|
|
||||||
cx.spawn(async move |shell, cx| {
|
|
||||||
loop {
|
|
||||||
let delay = match shell.update(cx, |shell, _| shell.external_web_surface_tick_delay()) {
|
|
||||||
Ok(delay) => delay,
|
|
||||||
Err(_) => break,
|
|
||||||
};
|
|
||||||
Timer::after(delay).await;
|
|
||||||
let result = shell.update(cx, |shell, cx| {
|
|
||||||
if shell.tick_external_web_surfaces(cx) {
|
|
||||||
cx.notify();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if result.is_err() {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.detach();
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
//! Long-lived shell timers, started once per window at construction.
|
||||||
|
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use gpui::{Context, Timer};
|
||||||
|
|
||||||
|
use super::{ElyShell, ShellState};
|
||||||
|
|
||||||
|
/// Idle tabs archive on this cadence when the active Space opts into an
|
||||||
|
/// idle policy; the sweep is a no-op for `ArchivePolicy::Manual`.
|
||||||
|
const IDLE_ARCHIVE_SWEEP_INTERVAL: Duration = Duration::from_secs(30 * 60);
|
||||||
|
|
||||||
|
pub(super) fn start(cx: &mut Context<ElyShell>) {
|
||||||
|
start_external_web_surface_timer(cx);
|
||||||
|
start_idle_archive_timer(cx);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn start_external_web_surface_timer(cx: &mut Context<ElyShell>) {
|
||||||
|
cx.spawn(async move |shell, cx| {
|
||||||
|
loop {
|
||||||
|
let delay = match shell.update(cx, |shell, _| shell.external_web_surface_tick_delay()) {
|
||||||
|
Ok(delay) => delay,
|
||||||
|
Err(_) => break,
|
||||||
|
};
|
||||||
|
Timer::after(delay).await;
|
||||||
|
let result = shell.update(cx, |shell, cx| {
|
||||||
|
if shell.tick_external_web_surfaces(cx) {
|
||||||
|
cx.notify();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if result.is_err() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn start_idle_archive_timer(cx: &mut Context<ElyShell>) {
|
||||||
|
cx.spawn(async move |shell, cx| {
|
||||||
|
loop {
|
||||||
|
Timer::after(IDLE_ARCHIVE_SWEEP_INTERVAL).await;
|
||||||
|
let result = shell.update(cx, |shell, cx| {
|
||||||
|
let ShellState::Ready(core) = &mut shell.state else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
match core.archive_idle_tabs(std::time::SystemTime::now()) {
|
||||||
|
Ok(0) => {}
|
||||||
|
Ok(archived) => {
|
||||||
|
tracing::info!(
|
||||||
|
target: "ely::archive",
|
||||||
|
archived,
|
||||||
|
"idle archive sweep archived tabs",
|
||||||
|
);
|
||||||
|
shell.schedule_cloud_sync_upload(cx);
|
||||||
|
cx.notify();
|
||||||
|
}
|
||||||
|
Err(error) => {
|
||||||
|
tracing::warn!(
|
||||||
|
target: "ely::archive",
|
||||||
|
error = %error,
|
||||||
|
"idle archive sweep failed",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if result.is_err() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.detach();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user