1#![deny(clippy::arithmetic_side_effects)]
2#![deny(clippy::cast_possible_truncation)]
3#![deny(unused_crate_dependencies)]
4#![deny(warnings)]
5
6#[cfg(test)]
7use tracing_subscriber as _;
8
9use crate::service::genesis::NotifyCancel;
10use tokio_util::sync::CancellationToken;
11
12pub const VERSION: &str = env!("CARGO_PKG_VERSION");
13
14#[doc(no_inline)]
15pub use fuel_core_chain_config as chain_config;
16#[cfg(feature = "p2p")]
17#[doc(no_inline)]
18pub use fuel_core_p2p as p2p;
19#[cfg(feature = "parallel-executor")]
20#[doc(no_inline)]
21pub use fuel_core_parallel_executor as parallel_executor;
22#[doc(no_inline)]
23pub use fuel_core_producer as producer;
24#[cfg(feature = "relayer")]
25#[doc(no_inline)]
26pub use fuel_core_relayer as relayer;
27#[cfg(feature = "p2p")]
28#[doc(no_inline)]
29pub use fuel_core_sync as sync;
30#[doc(no_inline)]
31pub use fuel_core_tx_status_manager as tx_status_manager;
32#[doc(no_inline)]
33pub use fuel_core_txpool as txpool;
34#[doc(no_inline)]
35pub use fuel_core_types as types;
36#[doc(no_inline)]
37pub use fuel_core_upgradable_executor as upgradable_executor;
38
39pub mod coins_query;
40pub mod combined_database;
41pub mod database;
42pub mod executor;
43pub mod model;
44#[cfg(all(feature = "p2p", feature = "test-helpers"))]
45pub mod p2p_test_helpers;
46pub mod query;
47pub mod schema;
48pub mod service;
49pub mod state;
50
51mod graphql_api;
53
54pub mod fuel_core_graphql_api {
55 pub use crate::graphql_api::*;
56}
57
58#[cfg(test)]
59fuel_core_trace::enable_tracing!();
60
61#[derive(Clone)]
62pub struct ShutdownListener {
63 pub token: CancellationToken,
64}
65
66impl ShutdownListener {
67 pub fn spawn() -> Self {
68 let token = CancellationToken::new();
69 {
70 let token = token.clone();
71 tokio::spawn(async move {
72 let mut sigterm = tokio::signal::unix::signal(
73 tokio::signal::unix::SignalKind::terminate(),
74 )?;
75
76 let mut sigint = tokio::signal::unix::signal(
77 tokio::signal::unix::SignalKind::interrupt(),
78 )?;
79 #[cfg(unix)]
80 tokio::select! {
81 _ = sigterm.recv() => {
82 tracing::info!("Received SIGTERM");
83 }
84 _ = sigint.recv() => {
85 tracing::info!("Received SIGINT");
86 }
87 }
88 #[cfg(not(unix))]
89 {
90 tokio::signal::ctrl_c().await?;
91 tracing::info!("Received ctrl_c");
92 }
93 token.cancel();
94 tokio::io::Result::Ok(())
95 });
96 }
97 Self { token }
98 }
99}
100
101impl NotifyCancel for ShutdownListener {
102 async fn wait_until_cancelled(&self) -> anyhow::Result<()> {
103 self.token.cancelled().await;
104 Ok(())
105 }
106
107 fn is_cancelled(&self) -> bool {
108 self.token.is_cancelled()
109 }
110}
111
112impl combined_database::ShutdownListener for ShutdownListener {
113 fn is_cancelled(&self) -> bool {
114 self.token.is_cancelled()
115 }
116}