aria2_core/engine/command.rs
1use crate::error::Result;
2use async_trait::async_trait;
3use std::time::{Duration, Instant};
4
5#[derive(Debug, Clone, PartialEq)]
6pub enum CommandStatus {
7 Pending,
8 Running,
9 Completed,
10}
11
12/// Progress update sent from a download command to the engine via channel.
13/// This decouples the download task from the RequestGroup RwLock: instead of
14/// acquiring `group.write().await` on every batched progress checkpoint, the
15/// download task performs a cheap lock-free `send` and a single aggregator
16/// task applies the update to the `RequestGroup`.
17///
18/// Fields:
19/// - `completed_bytes`: total bytes downloaded so far for this command.
20/// - `download_speed`: current download speed in bytes/sec. `0` means the
21/// sender did not refresh the speed sample this tick (the aggregator keeps
22/// the previously cached value).
23/// - `upload_speed`: upload speed in bytes/sec (BT only; `0` for HTTP/FTP).
24#[derive(Debug, Clone)]
25pub struct ProgressUpdate {
26 /// Total bytes downloaded so far for this command.
27 pub completed_bytes: u64,
28 /// Current download speed in bytes/sec (0 if not yet calculated).
29 pub download_speed: u64,
30 /// Upload speed in bytes/sec (for BT, 0 for HTTP).
31 pub upload_speed: u64,
32}
33
34#[async_trait]
35pub trait Command: Send + Sync {
36 async fn execute(&mut self) -> Result<()>;
37
38 fn status(&self) -> CommandStatus;
39
40 fn timeout(&self) -> Option<Duration> {
41 None
42 }
43
44 /// Returns the instant at which this command started executing, if the
45 /// engine has informed the command via [`set_started_at`].
46 ///
47 /// The default implementation reports `None`; commands that wish to
48 /// self-report elapsed time (e.g. for `status()` queries) may override
49 /// this together with [`set_started_at`].
50 fn started_at(&self) -> Option<Instant> {
51 None
52 }
53
54 /// Called by the engine immediately before the command is spawned onto a
55 /// background task. The default implementation is a no-op; commands that
56 /// store the instant can expose it through [`started_at`].
57 fn set_started_at(&mut self, _instant: Instant) {}
58}