Skip to content

Commit cc49f4d

Browse files
authored
Merge pull request #98 from firstbatchxyz/erhant/graceful-cancellation [skip ci]
Fixed cancellation signal issue
2 parents a487e7f + de9f73a commit cc49f4d

File tree

4 files changed

+59
-33
lines changed

4 files changed

+59
-33
lines changed

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ pub(crate) mod utils;
1010

1111
/// Crate version of the compute node.
1212
/// This value is attached within the published messages.
13-
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
13+
pub const DRIA_COMPUTE_NODE_VERSION: &str = env!("CARGO_PKG_VERSION");
1414

1515
pub use config::DriaComputeNodeConfig;
1616
pub use node::DriaComputeNode;

src/main.rs

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
use tokio_util::sync::CancellationToken;
2-
31
use dkn_compute::{DriaComputeNode, DriaComputeNodeConfig};
2+
use tokio::signal::unix::{signal, SignalKind};
3+
use tokio_util::sync::CancellationToken;
44

55
#[tokio::main]
66
async fn main() -> Result<(), Box<dyn std::error::Error>> {
@@ -13,7 +13,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
1313
.init();
1414
log::info!(
1515
"Initializing Dria Compute Node (version {})",
16-
dkn_compute::VERSION
16+
dkn_compute::DRIA_COMPUTE_NODE_VERSION
1717
);
1818

1919
// create configurations & check required services
@@ -23,12 +23,58 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
2323
panic!("Service check failed.")
2424
}
2525

26+
let token = CancellationToken::new();
27+
2628
// 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+
}
3175
};
3276

77+
log::info!("Terminating the node...");
78+
cancellation.cancel();
3379
Ok(())
3480
}

src/node.rs

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
use std::{str::FromStr, time::Duration};
2-
31
use libp2p::{gossipsub, Multiaddr};
4-
use tokio::signal::unix::{signal, SignalKind};
2+
use std::{str::FromStr, time::Duration};
53
use tokio_util::sync::CancellationToken;
64

75
use crate::{
@@ -217,7 +215,7 @@ impl DriaComputeNode {
217215

218216
}
219217
},
220-
_ = wait_for_termination(self.cancellation.clone()) => break,
218+
_ = self.cancellation.cancelled() => break,
221219
}
222220
}
223221

@@ -273,24 +271,6 @@ impl DriaComputeNode {
273271
}
274272
}
275273

276-
/// Waits for SIGTERM or SIGINT, and cancels the given token when the signal is received.
277-
async fn wait_for_termination(cancellation: CancellationToken) -> std::io::Result<()> {
278-
let mut sigterm = signal(SignalKind::terminate())?; // Docker sends SIGTERM
279-
let mut sigint = signal(SignalKind::interrupt())?; // Ctrl+C sends SIGINT
280-
tokio::select! {
281-
_ = sigterm.recv() => log::warn!("Recieved SIGTERM"),
282-
_ = sigint.recv() => log::warn!("Recieved SIGINT"),
283-
_ = cancellation.cancelled() => {
284-
// no need to wait if cancelled anyways
285-
return Ok(());
286-
}
287-
};
288-
289-
log::info!("Terminating the node...");
290-
cancellation.cancel();
291-
Ok(())
292-
}
293-
294274
#[cfg(test)]
295275
mod tests {
296276
use crate::{p2p::P2PMessage, DriaComputeNode, DriaComputeNodeConfig};

src/p2p/message.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ impl P2PMessage {
3939
Self {
4040
payload: BASE64_STANDARD.encode(payload),
4141
topic: topic.to_string(),
42-
version: crate::VERSION.to_string(),
42+
version: crate::DRIA_COMPUTE_NODE_VERSION.to_string(),
4343
timestamp: get_current_time_nanos(),
4444
}
4545
}
@@ -197,7 +197,7 @@ mod tests {
197197
"{\"hello\":\"world\"}"
198198
);
199199
assert_eq!(message.topic, "test-topic");
200-
assert_eq!(message.version, crate::VERSION);
200+
assert_eq!(message.version, crate::DRIA_COMPUTE_NODE_VERSION);
201201
assert!(message.timestamp > 0);
202202

203203
let parsed_body = message.parse_payload(false).expect("Should decode");
@@ -224,7 +224,7 @@ mod tests {
224224
"{\"hello\":\"world\"}"
225225
);
226226
assert_eq!(message.topic, "test-topic");
227-
assert_eq!(message.version, crate::VERSION);
227+
assert_eq!(message.version, crate::DRIA_COMPUTE_NODE_VERSION);
228228
assert!(message.timestamp > 0);
229229

230230
assert!(message.is_signed(&pk).expect("Should check signature"));

0 commit comments

Comments
 (0)