Refactored Progress Bar
Build Library / Build Library (push) Successful in 5m54s

Refactored Progress Bar to remove multiprogress bar and only draw one instance. #36 is still open and not fixed with this push, but I believe this is the way to fix the issue.
Also implemented an Arc Mutex on the progress bar so it can be controlled via different threads.
This commit is contained in:
brotoskyj
2025-12-05 17:19:40 -05:00
parent 154a7efcc8
commit 0ac3b54d89
6 changed files with 28 additions and 16 deletions
+1 -1
View File
@@ -26,7 +26,7 @@ dependencies = [
[[package]] [[package]]
name = "airlock_libs" name = "airlock_libs"
version = "5.1.2" version = "5.2.0"
dependencies = [ dependencies = [
"chrono", "chrono",
"crossbeam", "crossbeam",
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "airlock_libs" name = "airlock_libs"
version = "5.1.2" version = "5.2.0"
edition = "2024" edition = "2024"
[lib] [lib]
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "maturin"
[project] [project]
name = "airlock_libs" name = "airlock_libs"
version = "5.1.2" version = "5.2.0"
description = "Airlock Digital API Wrapper" description = "Airlock Digital API Wrapper"
readme = "README.md" readme = "README.md"
license = { text = "AGPL-3.0-only" } license = { text = "AGPL-3.0-only" }
+23 -11
View File
@@ -1,7 +1,8 @@
use std::thread;
use crossbeam::channel::unbounded;
use crate::modules::datatypes::*; use crate::modules::datatypes::*;
use crate::prelude::*; use crate::prelude::*;
use crossbeam::channel::unbounded;
use std::sync::{Arc, Mutex};
use std::thread;
#[pyfunction] #[pyfunction]
pub fn pull_policy_exec_histories( pub fn pull_policy_exec_histories(
py: Python<'_>, py: Python<'_>,
@@ -72,15 +73,16 @@ pub fn pull_policy_exec_histories(
} }
} }
let mut checkpoint_number: String = SkipBack::find_checkpoint(days).to_string(); let mut checkpoint_number: String = SkipBack::find_checkpoint(days).to_string();
let multi_progress: MultiProgress = MultiProgress::new(); let progress_bar = Arc::new(Mutex::new(ProgressBar::new(100)));
multi_progress.set_draw_target(ProgressDrawTarget::stderr()); progress_bar
let progress_bar: ProgressBar = multi_progress.add(ProgressBar::new(100)); .lock()
progress_bar.set_style( .unwrap()
.set_draw_target(ProgressDrawTarget::stderr());
progress_bar.lock().unwrap().set_style(
ProgressStyle::default_bar() ProgressStyle::default_bar()
.template("Total Completion: {spinner:.green} [{elapsed_precise}] [{bar:40.green/blue}] {pos}/{len} {message}") .template("Total Completion: {spinner:.green} [{elapsed_precise}] [{bar:40.green/blue}] {pos}/{len} {message}")
.unwrap(), .unwrap(),
); );
progress_bar.enable_steady_tick(std::time::Duration::from_millis(100));
let client: Client = tracer.in_span("Building HTTP Client", |cx| { let client: Client = tracer.in_span("Building HTTP Client", |cx| {
let client_result: Result<Client, reqwest::Error> = build_client(headers); let client_result: Result<Client, reqwest::Error> = build_client(headers);
match client_result { match client_result {
@@ -111,6 +113,7 @@ pub fn pull_policy_exec_histories(
}); });
let cutoff: chrono::NaiveDateTime = Local::now().naive_local() - Duration::days(days); let cutoff: chrono::NaiveDateTime = Local::now().naive_local() - Duration::days(days);
let (tx, rx) = unbounded::<Vec<Group>>(); let (tx, rx) = unbounded::<Vec<Group>>();
let pb_clone = progress_bar.clone();
thread::spawn(move || { thread::spawn(move || {
let mut seen: HashMap<(String, String, String), Group> = if writeable_filepath.exists() let mut seen: HashMap<(String, String, String), Group> = if writeable_filepath.exists()
{ {
@@ -178,6 +181,10 @@ pub fn pull_policy_exec_histories(
}); });
let mut first_date: Option<NaiveDate> = None; let mut first_date: Option<NaiveDate> = None;
tracer.in_span("Airlock Data Retreival", |cx| { tracer.in_span("Airlock Data Retreival", |cx| {
pb_clone
.lock()
.unwrap()
.enable_steady_tick(std::time::Duration::from_millis(100));
let span: opentelemetry::trace::SpanRef<'_> = cx.span(); let span: opentelemetry::trace::SpanRef<'_> = cx.span();
span.set_attribute(Key::new("Days").string(days.to_string())); span.set_attribute(Key::new("Days").string(days.to_string()));
span.set_attribute(KeyValue::new("Policy Name", policy_names.clone())); span.set_attribute(KeyValue::new("Policy Name", policy_names.clone()));
@@ -213,16 +220,21 @@ pub fn pull_policy_exec_histories(
} }
if let Some(base_date) = first_date { if let Some(base_date) = first_date {
let date_diff: chrono::TimeDelta = last_date - base_date; let date_diff: chrono::TimeDelta = last_date - base_date;
let total_span: i64 = (Local::now().naive_local().date() - base_date).num_days(); let total_span: i64 =
let percentage: u64 = ((date_diff.num_days() as f64 / total_span as f64) * 100.0) (Local::now().naive_local().date() - base_date).num_days();
let percentage: u64 = ((date_diff.num_days() as f64 / total_span as f64)
* 100.0)
.clamp(0.0, 100.0) .clamp(0.0, 100.0)
.round() as u64; .round() as u64;
progress_bar.set_position(percentage); pb_clone.lock().unwrap().set_position(percentage);
} }
} }
} }
}); });
progress_bar.finish_with_message("All Checkpoints Complete"); progress_bar
.lock()
.unwrap()
.finish_with_message("All Checkpoints Complete");
let return_data: String = match fs::read_to_string(file_path.clone()) { let return_data: String = match fs::read_to_string(file_path.clone()) {
Ok(return_data) => return_data, Ok(return_data) => return_data,
Err(e) => { Err(e) => {
+1 -1
View File
@@ -11,4 +11,4 @@ urllib3==2.5.0
pyperclip==1.11.0 pyperclip==1.11.0
--extra-index-url https://git.racooncity.org/api/packages/brotoskyj/pypi/simple/ --extra-index-url https://git.racooncity.org/api/packages/brotoskyj/pypi/simple/
airlock_libs==5.1.2 airlock_libs==5.2.0