Skip to content

Commit 806adc4

Browse files
committed
Refactor WebServer and runner for improved error handling and configuration management
1 parent 5797d5f commit 806adc4

File tree

3 files changed

+30
-29
lines changed

3 files changed

+30
-29
lines changed

crates/web/src/server.rs

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -107,19 +107,11 @@ impl WebServer {
107107
self,
108108
addr: std::net::SocketAddr,
109109
cancel_token: CancellationToken,
110-
) -> tokio::task::JoinHandle<()> {
110+
) -> edgelink_core::Result<tokio::task::JoinHandle<()>> {
111111
let router = self.router();
112-
tokio::spawn(async move {
113-
let listener = match TcpListener::bind(&addr).await {
114-
Ok(listener) => listener,
115-
Err(e) => {
116-
log::error!("Failed to bind to address {addr}: {e}");
117-
return;
118-
}
119-
};
120-
112+
let listener = TcpListener::bind(&addr).await?;
113+
Ok(tokio::spawn(async move {
121114
let server = serve(listener, router);
122-
123115
tokio::select! {
124116
result = server => {
125117
if let Err(e) = result {
@@ -130,6 +122,6 @@ impl WebServer {
130122
log::info!("Web server shutting down gracefully...");
131123
}
132124
}
133-
})
125+
}))
134126
}
135127
}

src/cliargs.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,13 @@ impl CliArgs {
9191
builder: config::ConfigBuilder<config::builder::DefaultState>,
9292
) -> Result<config::ConfigBuilder<config::builder::DefaultState>, config::ConfigError> {
9393
let mut builder = builder;
94-
// flows_path (from subcommand Run)
95-
if let Some(Commands::Run { flows_path: Some(fp), .. }) = &self.command {
96-
builder = builder.set_override("flows_path", fp.clone())?;
94+
// Handle all Run subcommand parameters together
95+
if let Some(Commands::Run { flows_path, bind, headless }) = &self.command {
96+
if let Some(fp) = flows_path {
97+
builder = builder.set_override("flows_path", fp.clone())?;
98+
}
99+
builder = builder.set_override("bind", bind.clone())?;
100+
builder = builder.set_override("headless", *headless)?;
97101
}
98102
// verbose
99103
builder = builder.set_override("verbose", self.verbose as i64)?;
@@ -113,7 +117,6 @@ impl CliArgs {
113117
if let Some(ref home) = self.home {
114118
builder = builder.set_override("home", home.clone())?;
115119
}
116-
// 其他参数可按需添加
117120
Ok(builder)
118121
}
119122
}

src/runner.rs

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
use edgelink_core::runtime::paths;
21
use std::path::PathBuf;
32
use std::sync::Arc;
3+
44
use tokio::task::JoinHandle;
55
use tokio_util::sync::CancellationToken;
66

7+
use edgelink_core::runtime::paths;
78
use edgelink_web::server::WebServer;
89

910
use crate::app::App;
@@ -14,7 +15,7 @@ use crate::env::EdgelinkEnv;
1415
use crate::logging;
1516
use crate::registry::list_available_nodes;
1617

17-
pub async fn run_app(cli_args: Arc<CliArgs>) -> anyhow::Result<()> {
18+
pub async fn run_app(cli_args: Arc<CliArgs>) -> edgelink_core::Result<()> {
1819
match &cli_args.command {
1920
Some(Commands::Run { flows_path: _, headless: _, bind: _ }) => run_app_internal(cli_args.clone()).await,
2021
Some(Commands::List) => list_available_nodes().await,
@@ -23,7 +24,7 @@ pub async fn run_app(cli_args: Arc<CliArgs>) -> anyhow::Result<()> {
2324
}
2425
}
2526

26-
pub async fn run_app_internal(cli_args: Arc<CliArgs>) -> anyhow::Result<()> {
27+
pub async fn run_app_internal(cli_args: Arc<CliArgs>) -> edgelink_core::Result<()> {
2728
if cli_args.verbose > 0 {
2829
eprintln!("EdgeLink v{} - #{}\n", consts::APP_VERSION, consts::GIT_HASH);
2930
eprintln!("Loading configuration...");
@@ -60,27 +61,32 @@ pub async fn run_app_internal(cli_args: Arc<CliArgs>) -> anyhow::Result<()> {
6061
let app = Arc::new(App::new(cli_args.clone(), env, None).await?);
6162

6263
let headless = app.env().config.get_bool("headless").unwrap_or(false);
63-
let web_server_handle: Option<JoinHandle<()>> =
64-
if !headless { Some(start_web_server(app.clone(), &app.env().config, cancel.clone()).await?) } else { None };
65-
66-
let app_result = app.run(cancel.child_token()).await;
67-
68-
if let Some(handle) = web_server_handle {
69-
handle.abort();
64+
use tokio::try_join;
65+
if headless {
66+
try_join!(app.run(cancel.child_token()), async { Ok(()) })?;
67+
} else {
68+
let handle = start_web_server(app.clone(), &app.env().config, cancel.clone()).await?;
69+
let app_fut = app.run(cancel.child_token());
70+
let web_fut = async {
71+
handle.await.map_err(|e| anyhow::anyhow!("Web server task failed: {e}"))?;
72+
Ok(())
73+
};
74+
try_join!(app_fut, web_fut)?;
7075
}
7176

77+
// 等待 cancel token 完成
7278
tokio::time::timeout(tokio::time::Duration::from_secs(10), cancel.cancelled()).await?;
7379
log::info!("Bye!");
7480

75-
app_result
81+
Ok(())
7682
}
7783

7884
/// Start the web server with the given configuration
7985
async fn start_web_server(
8086
app: Arc<App>,
8187
cfg: &config::Config,
8288
cancel: CancellationToken,
83-
) -> anyhow::Result<JoinHandle<()>> {
89+
) -> edgelink_core::Result<JoinHandle<()>> {
8490
// Determine static directory at runtime
8591
let static_dir = paths::ui_static_dir();
8692
log::info!("Using static directory: {}", static_dir.display());
@@ -131,5 +137,5 @@ async fn start_web_server(
131137
log::info!(" GET http://{addr}/api/admin/settings");
132138
log::info!("Health check: http://{addr}/api/health");
133139

134-
Ok(web_server.spawn(addr, cancel.clone()).await)
140+
web_server.spawn(addr, cancel.clone()).await
135141
}

0 commit comments

Comments
 (0)