fixed coord timeouts
This commit is contained in:
+12
-3
@@ -113,7 +113,7 @@ pub async fn run_coordinator(
|
|||||||
}
|
}
|
||||||
maybe_finished = handlers.join_next(), if !handlers.is_empty() => {
|
maybe_finished = handlers.join_next(), if !handlers.is_empty() => {
|
||||||
if let Some(join_result) = maybe_finished {
|
if let Some(join_result) = maybe_finished {
|
||||||
join_result??;
|
log_worker_result(join_result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -124,7 +124,7 @@ pub async fn run_coordinator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
while let Some(join_result) = handlers.join_next().await {
|
while let Some(join_result) = handlers.join_next().await {
|
||||||
join_result??;
|
log_worker_result(join_result);
|
||||||
}
|
}
|
||||||
|
|
||||||
let duration = start.elapsed().as_secs_f64();
|
let duration = start.elapsed().as_secs_f64();
|
||||||
@@ -175,6 +175,14 @@ pub async fn run_coordinator(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn log_worker_result(result: std::result::Result<Result<()>, tokio::task::JoinError>) {
|
||||||
|
match result {
|
||||||
|
Ok(Ok(())) => {}
|
||||||
|
Ok(Err(err)) => eprintln!("worker handler ended with error: {err:#}"),
|
||||||
|
Err(err) => eprintln!("worker task failed: {err}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn handle_worker(
|
async fn handle_worker(
|
||||||
stream: TcpStream,
|
stream: TcpStream,
|
||||||
peer: std::net::SocketAddr,
|
peer: std::net::SocketAddr,
|
||||||
@@ -194,7 +202,8 @@ async fn handle_worker(
|
|||||||
let worker_name = match lines.next_line().await? {
|
let worker_name = match lines.next_line().await? {
|
||||||
Some(line) if line.starts_with("HELLO ") => line[6..].trim().to_string(),
|
Some(line) if line.starts_with("HELLO ") => line[6..].trim().to_string(),
|
||||||
Some(line) => {
|
Some(line) => {
|
||||||
return Err(anyhow!("unexpected worker handshake from {peer}: {line}"));
|
eprintln!("rejected non-worker connection from {peer}: {line}");
|
||||||
|
return Ok(());
|
||||||
}
|
}
|
||||||
None => return Ok(()),
|
None => return Ok(()),
|
||||||
};
|
};
|
||||||
|
|||||||
+101
-20
@@ -1,9 +1,13 @@
|
|||||||
use crate::{config::Config, scan::check_port_open, terminal::TerminalUi};
|
use crate::{
|
||||||
|
config::Config,
|
||||||
|
scan::check_port_open,
|
||||||
|
terminal::{ScreenState, TerminalUi},
|
||||||
|
};
|
||||||
use anyhow::{anyhow, Context, Result};
|
use anyhow::{anyhow, Context, Result};
|
||||||
use std::{net::Ipv4Addr, sync::Arc};
|
use std::{net::Ipv4Addr, sync::Arc};
|
||||||
use tokio::{
|
use tokio::{
|
||||||
io::{AsyncBufReadExt, AsyncWriteExt, BufReader},
|
io::{AsyncBufReadExt, AsyncWriteExt, BufReader},
|
||||||
net::TcpStream,
|
net::{tcp::OwnedWriteHalf, TcpStream},
|
||||||
task::JoinSet,
|
task::JoinSet,
|
||||||
time::sleep,
|
time::sleep,
|
||||||
};
|
};
|
||||||
@@ -13,6 +17,36 @@ pub async fn run_worker(config: Config, ui: Arc<TerminalUi>) -> Result<()> {
|
|||||||
ui.print_banner();
|
ui.print_banner();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loop {
|
||||||
|
render_worker_status(&ui, "conectando", 0, 0);
|
||||||
|
|
||||||
|
match run_worker_session(&config, &ui).await? {
|
||||||
|
WorkerSession::Done => break,
|
||||||
|
WorkerSession::Disconnected => {
|
||||||
|
eprintln!("coordinator connection lost; reconnecting...");
|
||||||
|
sleep(std::time::Duration::from_secs(1)).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ui.is_enabled() {
|
||||||
|
ui.render(&ScreenState {
|
||||||
|
current_ip: "concluído".to_string(),
|
||||||
|
tested: 0,
|
||||||
|
total: 0,
|
||||||
|
});
|
||||||
|
ui.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
enum WorkerSession {
|
||||||
|
Done,
|
||||||
|
Disconnected,
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn run_worker_session(config: &Config, ui: &TerminalUi) -> Result<WorkerSession> {
|
||||||
let stream = connect_with_retry(&config.coordinator_addr).await?;
|
let stream = connect_with_retry(&config.coordinator_addr).await?;
|
||||||
let (read_half, mut write_half) = stream.into_split();
|
let (read_half, mut write_half) = stream.into_split();
|
||||||
let mut lines = BufReader::new(read_half).lines();
|
let mut lines = BufReader::new(read_half).lines();
|
||||||
@@ -20,34 +54,50 @@ pub async fn run_worker(config: Config, ui: Arc<TerminalUi>) -> Result<()> {
|
|||||||
.write_all(format!("HELLO {}\n", config.worker_name).as_bytes())
|
.write_all(format!("HELLO {}\n", config.worker_name).as_bytes())
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
render_worker_status(ui, "aguardando job", 0, 0);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let Some(line) = lines.next_line().await? else {
|
let Some(line) = lines.next_line().await? else {
|
||||||
break;
|
return Ok(WorkerSession::Disconnected);
|
||||||
};
|
};
|
||||||
|
|
||||||
if line == "DONE" {
|
if line == "DONE" || line == "SHUTDOWN" {
|
||||||
break;
|
return Ok(WorkerSession::Done);
|
||||||
}
|
|
||||||
|
|
||||||
if line == "SHUTDOWN" {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let job = parse_job_line(&line)?;
|
let job = parse_job_line(&line)?;
|
||||||
let result =
|
render_job_start(ui, &job);
|
||||||
execute_job(&job.ips, config.port, config.timeout_ms, config.concurrency).await?;
|
let result = execute_job(
|
||||||
|
&job.ips,
|
||||||
|
config.port,
|
||||||
|
config.timeout_ms,
|
||||||
|
config.concurrency,
|
||||||
|
ui,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
let result_line = format!(
|
if write_result(&mut write_half, &job, &result).await.is_err() {
|
||||||
"RESULT {} {} {} {} {}\n",
|
return Ok(WorkerSession::Disconnected);
|
||||||
job.chunk_start,
|
}
|
||||||
job.chunk_end,
|
|
||||||
result.tested,
|
render_worker_status(ui, "aguardando job", result.tested, job.ips.len());
|
||||||
result.open_ips.len(),
|
|
||||||
format_ips(&result.open_ips)
|
|
||||||
);
|
|
||||||
write_half.write_all(result_line.as_bytes()).await?;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn write_result(
|
||||||
|
write_half: &mut OwnedWriteHalf,
|
||||||
|
job: &Job,
|
||||||
|
result: &JobOutcome,
|
||||||
|
) -> Result<()> {
|
||||||
|
let result_line = format!(
|
||||||
|
"RESULT {} {} {} {} {}\n",
|
||||||
|
job.chunk_start,
|
||||||
|
job.chunk_end,
|
||||||
|
result.tested,
|
||||||
|
result.open_ips.len(),
|
||||||
|
format_ips(&result.open_ips)
|
||||||
|
);
|
||||||
|
write_half.write_all(result_line.as_bytes()).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,11 +164,36 @@ fn parse_job_line(line: &str) -> Result<Job> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn render_job_start(ui: &TerminalUi, job: &Job) {
|
||||||
|
let current_ip = job
|
||||||
|
.ips
|
||||||
|
.first()
|
||||||
|
.map(ToString::to_string)
|
||||||
|
.unwrap_or_else(|| "sem IP".to_string());
|
||||||
|
render_worker_status(ui, ¤t_ip, 0, job.ips.len());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_worker_status(ui: &TerminalUi, current_ip: &str, tested: usize, total: usize) {
|
||||||
|
if ui.is_enabled() {
|
||||||
|
let display_total = if total == 0 && current_ip != "concluído" {
|
||||||
|
1
|
||||||
|
} else {
|
||||||
|
total
|
||||||
|
};
|
||||||
|
ui.render(&ScreenState {
|
||||||
|
current_ip: current_ip.to_string(),
|
||||||
|
tested,
|
||||||
|
total: display_total,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn execute_job(
|
async fn execute_job(
|
||||||
ips: &[Ipv4Addr],
|
ips: &[Ipv4Addr],
|
||||||
port: u16,
|
port: u16,
|
||||||
timeout_ms: u64,
|
timeout_ms: u64,
|
||||||
concurrency: usize,
|
concurrency: usize,
|
||||||
|
ui: &TerminalUi,
|
||||||
) -> Result<JobOutcome> {
|
) -> Result<JobOutcome> {
|
||||||
let mut tested = 0usize;
|
let mut tested = 0usize;
|
||||||
let mut open_ips = Vec::new();
|
let mut open_ips = Vec::new();
|
||||||
@@ -139,6 +214,12 @@ async fn execute_job(
|
|||||||
if is_open {
|
if is_open {
|
||||||
open_ips.push(ip);
|
open_ips.push(ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ui.render(&ScreenState {
|
||||||
|
current_ip: ip.to_string(),
|
||||||
|
tested,
|
||||||
|
total: ips.len(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
index = end;
|
index = end;
|
||||||
|
|||||||
Reference in New Issue
Block a user