mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-10-23 05:51:39 +00:00
Add server-side and test-side port retry mechanisms to handle race conditions
- Introduced a new plan to address port-in-use race conditions in both server and test environments. - Implemented a retry mechanism with exponential backoff for binding to known ports in `LiveServer::start()`. - Added a `respawn_with_new_port()` method in `TestServeSession` to handle transient port conflicts during tests. - Modified `wait_to_come_online()` to retry with a new port if the server process exits due to `AddrInUse`. - Updated `fresh_rebuild_read()` to include port retry logic, enhancing robustness against port conflicts. These changes aim to improve the reliability of server and test interactions by mitigating race conditions related to port usage.
This commit is contained in:
parent
bf56dc4733
commit
d9fa62c88e
6 changed files with 544 additions and 89 deletions
|
|
@ -11,6 +11,7 @@ mod util;
|
|||
use std::convert::Infallible;
|
||||
use std::net::SocketAddr;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::Duration;
|
||||
|
||||
use hyper::body::Incoming;
|
||||
use hyper::server::conn::http1;
|
||||
|
|
@ -77,7 +78,37 @@ impl LiveServer {
|
|||
|
||||
let rt = Runtime::new().unwrap();
|
||||
let exit_reason = rt.block_on(async move {
|
||||
let listener = TcpListener::bind(address).await.unwrap();
|
||||
let listener = {
|
||||
const MAX_BIND_ATTEMPTS: u32 = 5;
|
||||
const BASE_BACKOFF_MS: u64 = 200;
|
||||
let mut attempts = 0u32;
|
||||
loop {
|
||||
attempts += 1;
|
||||
match TcpListener::bind(address).await {
|
||||
Ok(listener) => break listener,
|
||||
Err(err)
|
||||
if err.kind() == std::io::ErrorKind::AddrInUse
|
||||
&& attempts < MAX_BIND_ATTEMPTS =>
|
||||
{
|
||||
let delay = BASE_BACKOFF_MS * 2u64.pow(attempts - 1);
|
||||
log::warn!(
|
||||
"Port {} in use, retrying in {}ms (attempt {}/{})",
|
||||
address.port(),
|
||||
delay,
|
||||
attempts,
|
||||
MAX_BIND_ATTEMPTS
|
||||
);
|
||||
tokio::time::sleep(Duration::from_millis(delay)).await;
|
||||
}
|
||||
Err(err) => {
|
||||
panic!(
|
||||
"Failed to bind to {}: {} (after {} attempts)",
|
||||
address, err, attempts
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
loop {
|
||||
tokio::select! {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue