docker_image_pusher/upload/
stats.rs1use std::time::{Duration, Instant};
4use std::sync::Arc;
5use tokio::sync::Mutex;
6
7#[derive(Debug, Clone)]
8pub struct UploadStats {
9 pub total_layers: usize,
10 pub completed_layers: usize,
11 pub failed_layers: usize,
12 pub total_bytes: u64,
13 pub uploaded_bytes: u64,
14 pub start_time: Instant,
15 pub concurrent_uploads: usize,
16 pub avg_speed: u64,
17 pub peak_speed: u64,
18}
19
20impl UploadStats {
21 pub fn new(total_layers: usize, total_bytes: u64, concurrent_uploads: usize) -> Self {
22 Self {
23 total_layers,
24 completed_layers: 0,
25 failed_layers: 0,
26 total_bytes,
27 uploaded_bytes: 0,
28 start_time: Instant::now(),
29 concurrent_uploads,
30 avg_speed: 0,
31 peak_speed: 0,
32 }
33 }
34
35 pub fn add_completed_layer(&mut self, layer_size: u64) {
36 self.completed_layers += 1;
37 self.uploaded_bytes += layer_size;
38 self.update_speeds();
39 }
40
41 pub fn add_failed_layer(&mut self) {
42 self.failed_layers += 1;
43 }
44
45 fn update_speeds(&mut self) {
46 let elapsed = self.start_time.elapsed().as_secs();
47 if elapsed > 0 {
48 let current_speed = self.uploaded_bytes / elapsed;
49 self.avg_speed = current_speed;
50 if current_speed > self.peak_speed {
51 self.peak_speed = current_speed;
52 }
53 }
54 }
55
56 pub fn completion_percentage(&self) -> f64 {
57 if self.total_layers == 0 {
58 100.0
59 } else {
60 (self.completed_layers as f64 / self.total_layers as f64) * 100.0
61 }
62 }
63
64 pub fn estimated_time_remaining(&self) -> Option<Duration> {
65 if self.avg_speed > 0 && self.uploaded_bytes < self.total_bytes {
66 let remaining_bytes = self.total_bytes - self.uploaded_bytes;
67 let remaining_seconds = remaining_bytes / self.avg_speed;
68 Some(Duration::from_secs(remaining_seconds))
69 } else {
70 None
71 }
72 }
73}
74
75pub type SharedStats = Arc<Mutex<UploadStats>>;