From 93e441d5b146f869a5d2038294441a1e77889324 Mon Sep 17 00:00:00 2001 From: JoukoVirtanen Date: Fri, 5 Jun 2026 21:18:07 -0700 Subject: [PATCH 1/7] X-Smart-Branch-Parent: main From 95eed51370f78e57cf1be05b9a8725bc3306f18a Mon Sep 17 00:00:00 2001 From: JoukoVirtanen Date: Wed, 3 Jun 2026 16:18:35 -0700 Subject: [PATCH 2/7] Fixed scripts/network/init.sh --- scripts/network/init.sh | 10 ++++++---- src/worker/network.rs | 15 +++++++++++++-- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/scripts/network/init.sh b/scripts/network/init.sh index eb9c30b..3a7416f 100755 --- a/scripts/network/init.sh +++ b/scripts/network/init.sh @@ -10,6 +10,8 @@ berserker -c /etc/berserker/network-server.toml & SERVER_PID=$! +sleep 1 + berserker -c /etc/berserker/network-client.toml & CLIENT_PID=$! @@ -17,12 +19,12 @@ CLIENT_PID=$! cleanup() { echo "Killing client ($CLIENT_PID) and server ($SERVER_PID)" - kill -9 "$CLIENT_PID" - kill -9 "$SERVER_PID" + kill -9 "$CLIENT_PID" 2>/dev/null + kill -9 "$SERVER_PID" 2>/dev/null exit } -trap cleanup SIGINT SIGABRT +trap cleanup SIGINT SIGABRT SIGTERM -wait -n "$SERVER_PID" "$CLIENT_PID" +wait "$SERVER_PID" "$CLIENT_PID" diff --git a/src/worker/network.rs b/src/worker/network.rs index 25b9149..34232a0 100644 --- a/src/worker/network.rs +++ b/src/worker/network.rs @@ -47,8 +47,19 @@ impl NetworkWorker { ) -> Result<(), WorkerError> { debug!("Starting server at {:?}:{:?}", addr, target_port); - let listener = - TcpListener::bind((addr.to_string(), target_port)).unwrap(); + let listener = loop { + match TcpListener::bind((addr.to_string(), target_port)) { + Ok(l) => break l, + Err(e) if e.kind() == std::io::ErrorKind::AddrInUse => { + info!( + "Address {}:{} in use, retrying in 1s", + addr, target_port + ); + thread::sleep(std::time::Duration::from_secs(1)); + } + Err(e) => panic!("Failed to bind: {}", e), + } + }; for stream in listener.incoming() { let mut stream = stream.unwrap(); From 8d973ecb806e953c719b018fc4964c38d0d52383 Mon Sep 17 00:00:00 2001 From: JoukoVirtanen Date: Thu, 4 Jun 2026 09:56:56 -0700 Subject: [PATCH 3/7] Only tries bind a maximum of 30 times --- src/worker/network.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/worker/network.rs b/src/worker/network.rs index 34232a0..ffb4fc5 100644 --- a/src/worker/network.rs +++ b/src/worker/network.rs @@ -47,14 +47,21 @@ impl NetworkWorker { ) -> Result<(), WorkerError> { debug!("Starting server at {:?}:{:?}", addr, target_port); + const MAX_BIND_RETRIES: u32 = 30; + let mut retries = 0; let listener = loop { match TcpListener::bind((addr.to_string(), target_port)) { Ok(l) => break l, Err(e) if e.kind() == std::io::ErrorKind::AddrInUse => { - info!( - "Address {}:{} in use, retrying in 1s", - addr, target_port - ); + retries += 1; + if retries > MAX_BIND_RETRIES { + return Err(WorkerError::InternalWithMessage( + format!( + "Failed to bind {}:{} after {} retries: {}", + addr, target_port, MAX_BIND_RETRIES, e + ), + )); + } thread::sleep(std::time::Duration::from_secs(1)); } Err(e) => panic!("Failed to bind: {}", e), From 85b95e80057f8660abfeb90d598f73787407c350 Mon Sep 17 00:00:00 2001 From: JoukoVirtanen Date: Thu, 4 Jun 2026 10:26:58 -0700 Subject: [PATCH 4/7] Fixed format --- src/worker/network.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/worker/network.rs b/src/worker/network.rs index ffb4fc5..4b2b955 100644 --- a/src/worker/network.rs +++ b/src/worker/network.rs @@ -55,12 +55,10 @@ impl NetworkWorker { Err(e) if e.kind() == std::io::ErrorKind::AddrInUse => { retries += 1; if retries > MAX_BIND_RETRIES { - return Err(WorkerError::InternalWithMessage( - format!( - "Failed to bind {}:{} after {} retries: {}", - addr, target_port, MAX_BIND_RETRIES, e - ), - )); + return Err(WorkerError::InternalWithMessage(format!( + "Failed to bind {}:{} after {} retries: {}", + addr, target_port, MAX_BIND_RETRIES, e + ))); } thread::sleep(std::time::Duration::from_secs(1)); } From 063b439546b56b2790b5a700a6c5a2cd6023e4db Mon Sep 17 00:00:00 2001 From: Jouko Virtanen Date: Fri, 5 Jun 2026 10:48:59 -0700 Subject: [PATCH 5/7] Apply suggestions from code review Co-authored-by: Mauro Ezequiel Moltrasio --- src/worker/network.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/worker/network.rs b/src/worker/network.rs index 4b2b955..b1d83aa 100644 --- a/src/worker/network.rs +++ b/src/worker/network.rs @@ -52,7 +52,7 @@ impl NetworkWorker { let listener = loop { match TcpListener::bind((addr.to_string(), target_port)) { Ok(l) => break l, - Err(e) if e.kind() == std::io::ErrorKind::AddrInUse => { + Err(e) if e.kind() == io::ErrorKind::AddrInUse => { retries += 1; if retries > MAX_BIND_RETRIES { return Err(WorkerError::InternalWithMessage(format!( @@ -60,7 +60,7 @@ impl NetworkWorker { addr, target_port, MAX_BIND_RETRIES, e ))); } - thread::sleep(std::time::Duration::from_secs(1)); + thread::sleep(Duration::from_secs(1)); } Err(e) => panic!("Failed to bind: {}", e), } From 5c8429afd47cf09a894931dedb34e9e96d0142c8 Mon Sep 17 00:00:00 2001 From: JoukoVirtanen Date: Sat, 6 Jun 2026 09:29:07 -0700 Subject: [PATCH 6/7] Fixed imports --- src/worker/network.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/worker/network.rs b/src/worker/network.rs index b1d83aa..6672d41 100644 --- a/src/worker/network.rs +++ b/src/worker/network.rs @@ -8,9 +8,11 @@ use std::str; use std::time::{SystemTime, UNIX_EPOCH}; use std::{ fmt::Display, + io, io::{BufReader, prelude::*}, net::TcpListener, thread, + time::Duration, }; use crate::{BaseConfig, Worker, WorkerError, Workload, WorkloadConfig}; From 93b1a0311a78af421c0e0554c0c4291d29abacdd Mon Sep 17 00:00:00 2001 From: JoukoVirtanen Date: Sat, 6 Jun 2026 10:03:44 -0700 Subject: [PATCH 7/7] Created a bind_port function --- src/worker/network.rs | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/src/worker/network.rs b/src/worker/network.rs index 6672d41..01b8617 100644 --- a/src/worker/network.rs +++ b/src/worker/network.rs @@ -39,6 +39,29 @@ impl NetworkWorker { } } + fn bind_port( + &self, + addr: Ipv4Address, + target_port: u16, + ) -> Result { + const MAX_BIND_RETRIES: usize = 30; + let addr = addr.to_string(); + for _ in 0..MAX_BIND_RETRIES { + match TcpListener::bind((addr.as_str(), target_port)) { + Ok(l) => return Ok(l), + Err(e) if e.kind() == io::ErrorKind::AddrInUse => { + thread::sleep(Duration::from_secs(1)); + } + Err(e) => panic!("Failed to bind: {}", e), + } + } + + Err(WorkerError::InternalWithMessage(format!( + "Failed to bind {}:{} after {} retries: address in use", + addr, target_port, MAX_BIND_RETRIES + ))) + } + /// Start a simple server. The client side is going to be a networking /// worker as well, so for convenience of troubleshooting do not error /// out if something unexpected happened, log and proceed instead. @@ -49,24 +72,7 @@ impl NetworkWorker { ) -> Result<(), WorkerError> { debug!("Starting server at {:?}:{:?}", addr, target_port); - const MAX_BIND_RETRIES: u32 = 30; - let mut retries = 0; - let listener = loop { - match TcpListener::bind((addr.to_string(), target_port)) { - Ok(l) => break l, - Err(e) if e.kind() == io::ErrorKind::AddrInUse => { - retries += 1; - if retries > MAX_BIND_RETRIES { - return Err(WorkerError::InternalWithMessage(format!( - "Failed to bind {}:{} after {} retries: {}", - addr, target_port, MAX_BIND_RETRIES, e - ))); - } - thread::sleep(Duration::from_secs(1)); - } - Err(e) => panic!("Failed to bind: {}", e), - } - }; + let listener = self.bind_port(addr, target_port)?; for stream in listener.incoming() { let mut stream = stream.unwrap();