1
- use tokio_util:: sync:: CancellationToken ;
2
-
3
1
use dkn_compute:: { DriaComputeNode , DriaComputeNodeConfig } ;
2
+ use tokio:: signal:: unix:: { signal, SignalKind } ;
3
+ use tokio_util:: sync:: CancellationToken ;
4
4
5
5
#[ tokio:: main]
6
6
async fn main ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
@@ -13,7 +13,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
13
13
. init ( ) ;
14
14
log:: info!(
15
15
"Initializing Dria Compute Node (version {})" ,
16
- dkn_compute:: VERSION
16
+ dkn_compute:: DRIA_COMPUTE_NODE_VERSION
17
17
) ;
18
18
19
19
// create configurations & check required services
@@ -23,12 +23,58 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
23
23
panic ! ( "Service check failed." )
24
24
}
25
25
26
+ let token = CancellationToken :: new ( ) ;
27
+
26
28
// launch the node
27
- let mut node = DriaComputeNode :: new ( config, CancellationToken :: new ( ) ) . await ?;
28
- if let Err ( err) = node. launch ( ) . await {
29
- log:: error!( "Node error: {}" , err) ;
30
- panic ! ( "Node failed." )
29
+ let node_token = token. clone ( ) ;
30
+ let node_handle = tokio:: spawn ( async move {
31
+ match DriaComputeNode :: new ( config, node_token) . await {
32
+ Ok ( mut node) => {
33
+ if let Err ( err) = node. launch ( ) . await {
34
+ log:: error!( "Node launch error: {}" , err) ;
35
+ panic ! ( "Node failed." )
36
+ } ;
37
+ }
38
+ Err ( err) => {
39
+ log:: error!( "Node setup error: {}" , err) ;
40
+ panic ! ( "Could not setup node." )
41
+ }
42
+ }
43
+ } ) ;
44
+
45
+ // add cancellation check
46
+ tokio:: spawn ( async move {
47
+ if let Err ( err) = wait_for_termination ( token. clone ( ) ) . await {
48
+ log:: error!( "Error waiting for termination: {}" , err) ;
49
+ log:: error!( "Cancelling due to unexpected error." ) ;
50
+ token. cancel ( ) ;
51
+ } ;
52
+ } ) ;
53
+
54
+ // wait for tasks to complete
55
+ if let Err ( err) = node_handle. await {
56
+ log:: error!( "Node handle error: {}" , err) ;
57
+ panic ! ( "Could not exit Node thread handle." ) ;
58
+ } ;
59
+
60
+ Ok ( ( ) )
61
+ }
62
+
63
+ /// Waits for SIGTERM or SIGINT, and cancels the given token when the signal is received.
64
+ async fn wait_for_termination ( cancellation : CancellationToken ) -> std:: io:: Result < ( ) > {
65
+ let mut sigterm = signal ( SignalKind :: terminate ( ) ) ?; // Docker sends SIGTERM
66
+ let mut sigint = signal ( SignalKind :: interrupt ( ) ) ?; // Ctrl+C sends SIGINT
67
+ tokio:: select! {
68
+ _ = sigterm. recv( ) => log:: warn!( "Recieved SIGTERM" ) ,
69
+ _ = sigint. recv( ) => log:: warn!( "Recieved SIGINT" ) ,
70
+ _ = cancellation. cancelled( ) => {
71
+ // no need to wait if cancelled anyways
72
+ // although this is not likely to happen
73
+ return Ok ( ( ) ) ;
74
+ }
31
75
} ;
32
76
77
+ log:: info!( "Terminating the node..." ) ;
78
+ cancellation. cancel ( ) ;
33
79
Ok ( ( ) )
34
80
}
0 commit comments