Refactored redis component to use a centralized postgres database with coordinator instead of descentralized sqlite shitty databases

This commit is contained in:
2026-06-30 18:07:47 -03:00
parent bae8712f3b
commit e81211c88e
10 changed files with 854 additions and 193 deletions
+165
View File
@@ -1,5 +1,7 @@
use std::io::{self, IsTerminal, Write};
use std::sync::Mutex;
use std::time::Duration;
use terminal_size::{terminal_size, Width};
pub const BANNER: [&str; 9] = [
" ░██████ ░██████ ",
@@ -25,6 +27,23 @@ pub struct TerminalUi {
lock: Mutex<()>,
}
#[derive(Debug, Clone)]
pub struct RedisWorkerScreenState {
pub worker_name: String,
pub queue_name: String,
pub current_ip: String,
pub current_path: String,
pub current_status: String,
pub processed: usize,
pub captured: usize,
pub global_done: usize,
pub global_total: usize,
pub queue_remaining: Option<usize>,
pub block_done: usize,
pub block_total: usize,
pub elapsed: Duration,
}
impl TerminalUi {
pub fn new(enabled: bool) -> Self {
Self {
@@ -56,6 +75,104 @@ impl TerminalUi {
let _ = stdout.flush();
}
pub fn render_redis_worker(&self, state: &RedisWorkerScreenState) {
if !self.enabled {
return;
}
let _guard = self.lock.lock().expect("terminal mutex poisoned");
let mut stdout = io::stdout();
let width = terminal_width();
let content_width = width.saturating_sub(2).max(32);
let global_percent = percent(state.global_done, state.global_total);
let block_percent = percent(state.block_done, state.block_total);
let global_bar = progress_bar(global_percent, content_width.saturating_sub(24));
let block_bar = progress_bar(block_percent, content_width.saturating_sub(24));
let queue_remaining = state
.queue_remaining
.map(|value| value.to_string())
.unwrap_or_else(|| "?".to_string());
let _ = write!(stdout, "\x1b[2J\x1b[H\x1b[?25l");
let _ = writeln!(
stdout,
"{}",
fit_line(
&format!(
"CamFinder Redis Worker {} pid:{}",
state.worker_name,
std::process::id()
),
content_width
)
);
let _ = writeln!(stdout, "{}", "".repeat(content_width));
let _ = writeln!(
stdout,
"{}",
fit_line(&format!("Fila: {}", state.queue_name), content_width)
);
let _ = writeln!(
stdout,
"{}",
fit_line(
&format!(
"Global: [{}] {:>5.1}% {}/{} IPs redis:{}",
global_bar,
global_percent,
state.global_done,
state.global_total,
queue_remaining
),
content_width
)
);
let _ = writeln!(
stdout,
"{}",
fit_line(
&format!(
"Bloco : [{}] {:>5.1}% {}/{} tentativas",
block_bar, block_percent, state.block_done, state.block_total
),
content_width
)
);
let _ = writeln!(stdout, "{}", "".repeat(content_width));
let _ = writeln!(
stdout,
"{}",
fit_line(&format!("IP atual : {}", state.current_ip), content_width)
);
let _ = writeln!(
stdout,
"{}",
fit_line(&format!("Path : {}", state.current_path), content_width)
);
let _ = writeln!(
stdout,
"{}",
fit_line(
&format!("Status : {}", state.current_status),
content_width
)
);
let _ = writeln!(
stdout,
"{}",
fit_line(
&format!(
"Tentativas: {} Capturas: {} Tempo: {}",
state.processed,
state.captured,
format_duration(state.elapsed)
),
content_width
)
);
let _ = stdout.flush();
}
pub fn render(&self, state: &ScreenState) {
if !self.enabled {
return;
@@ -97,3 +214,51 @@ impl TerminalUi {
pub fn stdout_is_terminal() -> bool {
io::stdout().is_terminal()
}
fn terminal_width() -> usize {
terminal_size()
.map(|(Width(width), _)| usize::from(width))
.unwrap_or(80)
}
fn percent(done: usize, total: usize) -> f64 {
if total == 0 {
0.0
} else {
((done as f64 / total as f64) * 100.0).clamp(0.0, 100.0)
}
}
fn progress_bar(percent: f64, width: usize) -> String {
let width = width.clamp(8, 80);
let filled = ((percent / 100.0) * width as f64).round() as usize;
let empty = width.saturating_sub(filled);
format!("{}{}", "".repeat(filled), "".repeat(empty))
}
fn fit_line(value: &str, width: usize) -> String {
let chars = value.chars().collect::<Vec<_>>();
if chars.len() <= width {
return value.to_string();
}
if width <= 1 {
return "".to_string();
}
chars
.into_iter()
.take(width - 1)
.chain(std::iter::once('…'))
.collect()
}
fn format_duration(duration: Duration) -> String {
let total = duration.as_secs();
let hours = total / 3600;
let minutes = (total % 3600) / 60;
let seconds = total % 60;
if hours > 0 {
format!("{hours:02}:{minutes:02}:{seconds:02}")
} else {
format!("{minutes:02}:{seconds:02}")
}
}