Skip to content

Commit

Permalink
feat: add try_to_switch_to_an_available_port option
Browse files Browse the repository at this point in the history
  • Loading branch information
lomirus committed Dec 20, 2023
1 parent 0117892 commit 1455546
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 12 deletions.
10 changes: 6 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
//! use live_server::listen;
//!
//! async fn serve() {
//! listen("127.0.0.1", 8080, "./").await.unwrap();
//! listen("127.0.0.1", 8080, "./", true).await.unwrap();
//! }
//! ```
//!
Expand All @@ -31,23 +31,25 @@ static TX: OnceCell<broadcast::Sender<()>> = OnceCell::const_new();
/// use live_server::listen;
///
/// async fn serve() {
/// listen("127.0.0.1", 8080, "./").await.unwrap();
/// listen("127.0.0.1", 8080, "./", true).await.unwrap();
/// }
/// ```
pub async fn listen<R: Into<PathBuf>>(
host: &str,
port: u16,
root: R,
try_to_switch_to_an_available_port: bool
) -> Result<(), Box<dyn Error>> {
HOST.set(host.to_string()).unwrap();
ROOT.set(root.into()).unwrap();
let (tx, _) = broadcast::channel(16);
TX.set(tx).unwrap();

let watcher_future = tokio::spawn(watcher::watch());
let server_future = tokio::spawn(server::serve(port));
let server_future = tokio::spawn(server::serve(port, try_to_switch_to_an_available_port));

tokio::try_join!(watcher_future, server_future)?;
let (_, server_result) = tokio::try_join!(watcher_future, server_future)?;
server_result?;

Ok(())
}
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,5 @@ async fn main() {
},
};

listen(&host, args.port, args.root).await.unwrap();
listen(&host, args.port, args.root, true).await.unwrap();
}
19 changes: 13 additions & 6 deletions src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ use tokio::net::TcpListener;

use crate::{HOST, PORT, ROOT, TX};

pub async fn serve(port: u16) {
let listener = create_listener(port).await;
pub async fn serve(port: u16, switch_to_available_ports: bool) -> Result<(), String> {
let listener = create_listener(port, switch_to_available_ports).await?;
let app = create_server();
axum::serve(listener, app).await.unwrap();

Ok(())
}

async fn create_listener(port: u16) -> TcpListener {
async fn create_listener(port: u16, switch_to_available_ports: bool) -> Result<TcpListener, String> {
let host = HOST.get().unwrap();
let mut port = port;
// Loop until the port is available
Expand All @@ -28,12 +30,17 @@ async fn create_listener(port: u16) -> TcpListener {
Ok(listener) => {
log::info!("Listening on http://{}:{}/", host, port);
PORT.set(port).unwrap();
break listener;
break Ok(listener);
}
Err(err) => {
if let std::io::ErrorKind::AddrInUse = err.kind() {
log::warn!("Port {} is already in use", port);
port += 1;
if switch_to_available_ports {
log::warn!("Port {} is already in use", port);
port += 1;
} else {
log::error!("Port {} is already in use", port);
return Err(format!("Port {} is already in use", port));
}
} else {
log::error!("Failed to listen on {}:{}: {}", host, port, err);
}
Expand Down
2 changes: 1 addition & 1 deletion tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use reqwest::StatusCode;
#[tokio::test]
async fn request() {
tokio::spawn(async {
listen("127.0.0.1", 8000, "./tests/page").await.unwrap();
listen("127.0.0.1", 8000, "./tests/page", false).await.unwrap();
});

// Test requesting index.html
Expand Down

0 comments on commit 1455546

Please sign in to comment.