mirror of
https://github.com/narrrl/proton-drive-linux.git
synced 2026-11-03 16:41:26 +01:00
feat(core,fuse,gui,cli): pause/resume sync and a visible upload queue (phase 2)
Backend (docs/UI_UX_PLAN.md B-1, B-2):
- Request::SetSyncPaused { paused, until } pauses the drain worker and the
mirror reconcile. FUSE reads, write staging, the watcher and the poll keep
running. The pause is persisted in the `state` table (`sync_paused_until`),
so it survives a restart; a timed pause ends by itself through a timer
thread, re-armed on mount. Resuming wakes the drain and runs a full
reconcile. Response::Status gains `paused` and `paused_until`.
- Request::ListPendingOps lists the queue with paths, attempts, last error,
next attempt and parked/failing flags. Request::RetryPendingOp { id } makes
one backed-off op (or every failed one) due now. Parked ops are never
un-parked and nothing is dropped from the queue.
Front ends:
- Sync page: a status card with Pause/Resume (split button with 1 h, 8 h and
24 h pauses) and a "Waiting to Upload" list with Retry now and Retry All.
- The sidebar strip and the tray show the paused state; the tray gains Pause
Sync / Resume Sync and names failing changes.
- CLI: `pdfs sync pause [--for 30m|1h|2d]`, `pdfs sync resume`,
`pdfs sync queue`, `pdfs sync retry [id]`; `pdfs status` reports a pause.
Not in this phase: merging Activity into the Sync page, discarding a queued
op (needs a recovery copy first), and per-folder pause.
This commit is contained in:
1 parent
cf9e1665ca
commit
067561564e
17 files changed
+995
-13
No files matched your search
@@ -384,6 +384,18 @@ pub enum Request {
|
||||
/// Force a reconcile pass: one folder by id, or all when `id` is `None`.
|
||||
/// Replies with [`Response::Ok`].
|
||||
SyncNow { id: Option<i64> },
|
||||
/// Pause or resume syncing: queued uploads and changes stop draining and
|
||||
/// mirror folders stop reconciling, while reads through the mount keep
|
||||
/// working. `until` is the Unix second a pause ends by itself; `None`
|
||||
/// pauses until resumed. Ignored when resuming. Replies with
|
||||
/// [`Response::Ok`].
|
||||
SetSyncPaused { paused: bool, until: Option<i64> },
|
||||
/// List the queue of uploads and changes not yet on the remote. Replies
|
||||
/// with [`Response::PendingOps`].
|
||||
ListPendingOps,
|
||||
/// Retry a backed-off queued op now instead of waiting out its backoff;
|
||||
/// every failed op when `id` is `None`. Replies with [`Response::Ok`].
|
||||
RetryPendingOp { id: Option<i64> },
|
||||
/// List the folders under this machine's device that can be synced here,
|
||||
/// each with a proposed local path (features.md 5.2). Replies with
|
||||
/// [`Response::RestorableFolders`].
|
||||
@@ -626,6 +638,30 @@ pub struct DeviceInfo {
|
||||
pub adopted: bool,
|
||||
}
|
||||
|
||||
/// One queued upload or change (in [`Response::PendingOps`]).
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct PendingOpInfo {
|
||||
/// Queue row id, for [`Request::RetryPendingOp`].
|
||||
pub id: i64,
|
||||
/// `revision`, `create`, `mkdir`, `rename` or `trash`.
|
||||
pub kind: String,
|
||||
/// Mountpoint-relative path of the file or folder, or its name when the
|
||||
/// path is no longer known.
|
||||
pub path: String,
|
||||
/// Failed attempts so far.
|
||||
pub attempts: i64,
|
||||
/// The latest failure, when there has been one.
|
||||
pub last_error: Option<String>,
|
||||
/// Unix second the op was queued.
|
||||
pub queued_at: i64,
|
||||
/// Unix second of the next attempt; `None` while parked.
|
||||
pub next_attempt_at: Option<i64>,
|
||||
/// Held back until a transient file gets its final name.
|
||||
pub parked: bool,
|
||||
/// Failed often enough to count as stuck.
|
||||
pub failing: bool,
|
||||
}
|
||||
|
||||
/// One synced local folder on this machine's device (in [`Response::SyncFolders`]).
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct SyncFolderInfo {
|
||||
@@ -1562,6 +1598,13 @@ pub enum Response {
|
||||
/// Age of the oldest staged write, in seconds.
|
||||
#[serde(default)]
|
||||
staged_oldest_secs: u64,
|
||||
/// True while the user has sync paused (see [`Request::SetSyncPaused`]).
|
||||
#[serde(default)]
|
||||
paused: bool,
|
||||
/// The Unix second a timed pause ends; `None` when paused until
|
||||
/// resumed, or not paused.
|
||||
#[serde(default)]
|
||||
paused_until: Option<i64>,
|
||||
},
|
||||
/// A human-readable success message.
|
||||
Ok { message: String },
|
||||
@@ -1691,6 +1734,8 @@ pub enum Response {
|
||||
Locations { items: Vec<MountSpec> },
|
||||
/// This device's synced folders (reply to [`Request::ListSyncFolders`]).
|
||||
SyncFolders { items: Vec<SyncFolderInfo> },
|
||||
/// The upload/change queue (reply to [`Request::ListPendingOps`]).
|
||||
PendingOps { items: Vec<PendingOpInfo> },
|
||||
/// Folders offered for restore (reply to [`Request::ListRestorableFolders`]).
|
||||
RestorableFolders { items: Vec<RestorableFolder> },
|
||||
/// A node's share: members + pending invitations, and its public link if any
|
||||
|
||||
Reference in new issue
Block a user