History

implement progress trait for logs with throttling

Sebastian Thiel committed 6 years ago

Commit 287eca91 parent e82e63f5 files · +121 −6Browse files

Unified · Split

5 files
  1. Cargo.lock +10 −0
  2. Cargo.toml +1 −1
  3. git-features/Cargo.toml +4 −0
  4. git-features/src/progress.rs +103 −5
  5. tasks.md +3 −0
Cargo.lock+10−0
@@ -290,6 +290,7 @@ dependencies = [ · 289 unmodified lines
290 "crossbeam-utils",290 "crossbeam-utils",
291 "flume",291 "flume",
292 "git-object",292 "git-object",
293 "log",
293 "num_cpus",294 "num_cpus",
294 "sha-1",295 "sha-1",
295 "sha1",296 "sha1",
@@ -401,6 +402,15 @@ version = "0.2.71" · 105 unmodified lines
401source = "registry+https://github.com/rust-lang/crates.io-index"402source = "registry+https://github.com/rust-lang/crates.io-index"
402checksum = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49"403checksum = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49"
403 404
405[[package]]
406name = "log"
407version = "0.4.8"
408source = "registry+https://github.com/rust-lang/crates.io-index"
409checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
410dependencies = [
411 "cfg-if",
412]
413
404[[package]]414[[package]]
405name = "maybe-uninit"415name = "maybe-uninit"
406version = "2.0.0"416version = "2.0.0"
Cargo.toml+1−1
@@ -23,7 +23,7 @@ doctest = false · 22 unmodified lines
23default = ["fast", "pretty-cli"]23default = ["fast", "pretty-cli"]
24fast = ["git-features/parallel", "git-features/fast-sha1"]24fast = ["git-features/parallel", "git-features/fast-sha1"]
25pretty-cli = ["structopt"]25pretty-cli = ["structopt"]
26lean-cli = ["argh"]26lean-cli = ["argh", "git-features/progress-log"]
27 27
28[dependencies]28[dependencies]
29anyhow = "1.0.31"29anyhow = "1.0.31"
git-features/Cargo.toml+4−0
@@ -14,6 +14,7 @@ test = false · 13 unmodified lines
14[features]14[features]
15parallel = ["flume", "crossbeam-utils", "crossbeam-channel", "num_cpus"]15parallel = ["flume", "crossbeam-utils", "crossbeam-channel", "num_cpus"]
16fast-sha1 = ["fastsha1"]16fast-sha1 = ["fastsha1"]
17progress-log = ["log"]
17 18
18[dependencies]19[dependencies]
19# 'parallel' feature20# 'parallel' feature
@@ -27,3 +28,6 @@ sha1 = "0.6.0" · 7 unmodified lines
27crc = "1.8.1"28crc = "1.8.1"
28git-object = { version = "0.1.0", path = "../git-object" }29git-object = { version = "0.1.0", path = "../git-object" }
29fastsha1 = { package = "sha-1", version = "0.9.1", optional = true }30fastsha1 = { package = "sha-1", version = "0.9.1", optional = true }
31
32# progress
33log = { version = "0.4.8", optional = true }
git-features/src/progress.rs+103−5
@@ -1,8 +1,21 @@
1/// The severity of a message
2#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
3pub enum MessageLevel {
4 /// Rarely sent information related to the progress, not to be confused with the progress itself
5 Info,
6 /// Used to indicate that a task has failed, along with the reason
7 Failure,
8 /// Indicates a task was completed successfully
9 Success,
10}
11
1pub trait Progress {12pub trait Progress {
13 type SubProgress: Progress;
14
2 /// Adds a new child, whose parent is this instance, with the given name.15 /// Adds a new child, whose parent is this instance, with the given name.
3 ///16 ///
4 /// This will make the child progress to appear contained in the parent progress.17 /// This will make the child progress to appear contained in the parent progress.
5 fn add_child(&self, name: impl Into<String>) -> Self;18 fn add_child(&mut self, name: impl Into<String>) -> Self::SubProgress;
6 19
7 /// Initialize the Item for receiving progress information.20 /// Initialize the Item for receiving progress information.
8 ///21 ///
@@ -19,15 +32,100 @@ pub trait Progress { · 10 unmodified lines
19 /// **Note** that this method can be called multiple times, changing the bounded-ness and unit at will.32 /// **Note** that this method can be called multiple times, changing the bounded-ness and unit at will.
20 fn init(&mut self, max: Option<u32>, unit: Option<&'static str>);33 fn init(&mut self, max: Option<u32>, unit: Option<&'static str>);
21 34
22 /// Set the current progress to the given `step`.35 /// Set the current progress to the given `step`. The cost of this call is negligible,
36 /// making manual throttling *not* necessary.
23 ///37 ///
24 /// **Note**: that this call has no effect unless `init(…)` was called before.38 /// **Note**: that this call has no effect unless `init(…)` was called before.
25 fn set(&mut self, step: u32);39 fn set(&mut self, step: u32);
26 40
41 /// Create a `message` of the given `level` and store it with the progress tree.
42 ///
43 /// Use this to provide additional,human-readable information about the progress
44 /// made, including indicating success or failure.
45 fn message(&self, level: MessageLevel, message: impl Into<String>);
46
27 /// Create a message providing additional information about the progress thus far.47 /// Create a message providing additional information about the progress thus far.
28 fn info(&self, name: impl Into<String>) -> Self;48 fn info(&self, message: impl Into<String>) {
49 self.message(MessageLevel::Info, message)
50 }
29 /// Create a message indicating the task is done successfully51 /// Create a message indicating the task is done successfully
30 fn done(&self, name: impl Into<String>) -> Self;52 fn done(&self, message: impl Into<String>) {
53 self.message(MessageLevel::Success, message)
54 }
31 /// Create a message indicating the task failed55 /// Create a message indicating the task failed
32 fn fail(&self, name: impl Into<String>) -> Self;56 fn fail(&self, message: impl Into<String>) {
57 self.message(MessageLevel::Failure, message)
58 }
59}
60
61#[cfg(feature = "progress-log")]
62mod log {
63 use crate::progress::{MessageLevel, Progress};
64 use std::time::Duration;
65
66 pub struct LogProgress {
67 name: String,
68 max: Option<u32>,
69 unit: Option<&'static str>,
70 last_set: Option<std::time::SystemTime>,
71 }
72
73 const EMIT_LOG_EVERY_S: f32 = 0.5;
74
75 impl LogProgress {
76 pub fn new(name: impl Into<String>) -> Self {
77 LogProgress {
78 name: name.into(),
79 max: None,
80 unit: None,
81 last_set: None,
82 }
83 }
84 }
85
86 impl Progress for LogProgress {
87 type SubProgress = LogProgress;
88
89 fn add_child(&mut self, name: impl Into<String>) -> Self::SubProgress {
90 LogProgress::new(format!("{}::{}", self.name, Into::<String>::into(name)))
91 }
92
93 fn init(&mut self, max: Option<u32>, unit: Option<&'static str>) {
94 self.max = max;
95 self.unit = unit;
96 }
97
98 fn set(&mut self, step: u32) {
99 let now = std::time::SystemTime::now();
100 let last = self.last_set.unwrap_or(now);
101 if now
102 .duration_since(last)
103 .unwrap_or_else(|_| Duration::default())
104 .as_secs_f32()
105 > EMIT_LOG_EVERY_S
106 {
107 match (self.max, self.unit) {
108 (Some(max), Some(unit)) => {
109 log::info!("{} → {} / {} {}", self.name, step, max, unit)
110 }
111 (None, Some(unit)) => log::info!("{} → {} {}", self.name, step, unit),
112 (Some(max), None) => log::info!("{} → {} / {}", self.name, step, max),
113 (None, None) => log::info!("{} → {}", self.name, step),
114 }
115 }
116 self.last_set = Some(now);
117 }
118
119 fn message(&self, level: MessageLevel, message: impl Into<String>) {
120 let message: String = message.into();
121 match level {
122 MessageLevel::Info => log::info!("ℹ{} → {}", self.name, message),
123 MessageLevel::Failure => log::error!("𐄂{} → {}", self.name, message),
124 MessageLevel::Success => log::info!("✓{} → {}", self.name, message),
125 }
126 }
127 }
33}128}
129
130#[cfg(feature = "progress-log")]
131pub use self::log::LogProgress;
tasks.md+3−0
@@ -29,4 +29,7 @@ · 28 unmodified lines
29 * [ ] a verbose mode to list each object in a pack, similar to existing git-verify-pack29 * [ ] a verbose mode to list each object in a pack, similar to existing git-verify-pack
30* **stress**30* **stress**
31 * [ ] first stress test for validation of a big repository, linux maybe, or something smaller but big enough31 * [ ] first stress test for validation of a big repository, linux maybe, or something smaller but big enough
32* **unrelated**
33 * [ ] Use `argh` in cargo-diet to reduce build times
34 * [ ] Use `argh` in prodash dashboard example to reduce build times
32 35