1
- use edgelink_core:: runtime:: paths;
2
1
use std:: path:: PathBuf ;
3
2
use std:: sync:: Arc ;
3
+
4
4
use tokio:: task:: JoinHandle ;
5
5
use tokio_util:: sync:: CancellationToken ;
6
6
7
+ use edgelink_core:: runtime:: paths;
7
8
use edgelink_web:: server:: WebServer ;
8
9
9
10
use crate :: app:: App ;
@@ -14,7 +15,7 @@ use crate::env::EdgelinkEnv;
14
15
use crate :: logging;
15
16
use crate :: registry:: list_available_nodes;
16
17
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 < ( ) > {
18
19
match & cli_args. command {
19
20
Some ( Commands :: Run { flows_path : _, headless : _, bind : _ } ) => run_app_internal ( cli_args. clone ( ) ) . await ,
20
21
Some ( Commands :: List ) => list_available_nodes ( ) . await ,
@@ -23,7 +24,7 @@ pub async fn run_app(cli_args: Arc<CliArgs>) -> anyhow::Result<()> {
23
24
}
24
25
}
25
26
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 < ( ) > {
27
28
if cli_args. verbose > 0 {
28
29
eprintln ! ( "EdgeLink v{} - #{}\n " , consts:: APP_VERSION , consts:: GIT_HASH ) ;
29
30
eprintln ! ( "Loading configuration..." ) ;
@@ -60,27 +61,32 @@ pub async fn run_app_internal(cli_args: Arc<CliArgs>) -> anyhow::Result<()> {
60
61
let app = Arc :: new ( App :: new ( cli_args. clone ( ) , env, None ) . await ?) ;
61
62
62
63
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) ?;
70
75
}
71
76
77
+ // 等待 cancel token 完成
72
78
tokio:: time:: timeout ( tokio:: time:: Duration :: from_secs ( 10 ) , cancel. cancelled ( ) ) . await ?;
73
79
log:: info!( "Bye!" ) ;
74
80
75
- app_result
81
+ Ok ( ( ) )
76
82
}
77
83
78
84
/// Start the web server with the given configuration
79
85
async fn start_web_server (
80
86
app : Arc < App > ,
81
87
cfg : & config:: Config ,
82
88
cancel : CancellationToken ,
83
- ) -> anyhow :: Result < JoinHandle < ( ) > > {
89
+ ) -> edgelink_core :: Result < JoinHandle < ( ) > > {
84
90
// Determine static directory at runtime
85
91
let static_dir = paths:: ui_static_dir ( ) ;
86
92
log:: info!( "Using static directory: {}" , static_dir. display( ) ) ;
@@ -131,5 +137,5 @@ async fn start_web_server(
131
137
log:: info!( " GET http://{addr}/api/admin/settings" ) ;
132
138
log:: info!( "Health check: http://{addr}/api/health" ) ;
133
139
134
- Ok ( web_server. spawn ( addr, cancel. clone ( ) ) . await )
140
+ web_server. spawn ( addr, cancel. clone ( ) ) . await
135
141
}
0 commit comments