Skip to main content

coven_sync/
file_upload_queue.rs

1//! The upload queue as the app observes it (E7): the committed queue, with
2//! the uploads this process is sending now.
3
4pub use coven_database::UploadProgress;
5use coven_database::UploadQueueState;
6use coven_foundation::id_source::FileId;
7use std::time::SystemTime;
8
9/// Observable upload queue state (E7): one committed snapshot of the queue,
10/// with the uploads this process is sending as it is read.
11#[derive(Clone, Debug, PartialEq)]
12pub struct UploadQueue {
13    /// Whether transfer work is paused; persisted across reopening.
14    pub paused: bool,
15    /// Waiting files, oldest first. Files sharing one upload share its
16    /// place and progress.
17    pub files: Vec<QueuedUpload>,
18}
19/// One queued upload: whether it is being sent, and its committed progress.
20#[derive(Clone, Debug, PartialEq)]
21pub struct QueuedUpload {
22    /// The file its upload switches to the cloud.
23    pub file: FileId,
24    /// Whether this device is sending the file now.
25    pub phase: UploadPhase,
26    /// Progress the provider confirmed and this device persisted in the
27    /// file's resumable session; `None` while it has no session, as a file
28    /// sent in one request never does.
29    pub progress: Option<UploadProgress>,
30    /// Enqueue time.
31    pub queued_at: SystemTime,
32}
33/// Whether a queued file is being sent. Nothing about it is persisted: a
34/// reopened store starts with every file waiting.
35#[derive(Clone, Copy, Debug, PartialEq, Eq)]
36pub enum UploadPhase {
37    /// Not being sent: not started yet, paused, waiting for a free upload
38    /// slot or for its retry, or stored, waiting for the rest of its move
39    /// (ยง17.3).
40    Waiting,
41    /// An attempt is sending it now, in one request or in parts.
42    Uploading,
43}
44
45impl From<UploadQueueState> for UploadQueue {
46    /// Each file this process was sending as the queue was read is
47    /// uploading, beside the confirmed bytes its recorded session holds.
48    fn from(state: UploadQueueState) -> Self {
49        let files = state
50            .uploads
51            .into_iter()
52            .flat_map(|upload| {
53                let sending = &state.sending;
54                upload
55                    .files
56                    .iter()
57                    .map(move |file| QueuedUpload {
58                        phase: if sending.contains(file) {
59                            UploadPhase::Uploading
60                        } else {
61                            UploadPhase::Waiting
62                        },
63                        file: *file,
64                        progress: upload.progress,
65                        queued_at: upload.queued_at,
66                    })
67                    .collect::<Vec<_>>()
68            })
69            .collect();
70        Self { paused: state.paused, files }
71    }
72}