cat_gateway/service/utilities/health/
start.rs

1//! Utilities used for system `Started` functionality.
2
3use std::sync::atomic::{
4    AtomicBool,
5    Ordering::{Acquire, Relaxed, Release},
6};
7
8use tracing::{debug, info};
9
10/// Flag to determine if the service has started
11static STARTED: AtomicBool = AtomicBool::new(false);
12
13/// Flag to determine if the Indexing DB has started.
14static LIVE_INDEX_DB: AtomicBool = AtomicBool::new(false);
15
16/// Flag to determine if the Event DB has started.
17static LIVE_EVENT_DB: AtomicBool = AtomicBool::new(false);
18
19/// Flag to determine if the chain follower has synchronized with the IMMUTABLE tip for
20/// the first time.
21static INITIAL_IMMUTABLE_FOLLOWER_TIP_REACHED: AtomicBool = AtomicBool::new(false);
22
23/// Flag to determine if the chain follower has synchronized with the LIVE tip for the
24/// first time.
25static INITIAL_LIVE_FOLLOWER_TIP_REACHED: AtomicBool = AtomicBool::new(false);
26
27/// Returns whether the service has started or not.
28pub(crate) fn service_has_started() -> bool {
29    STARTED.load(Acquire)
30}
31
32/// Set the `STARTED` flag to `true`
33pub(crate) fn set_to_started() {
34    STARTED.store(true, Release);
35}
36
37/// Returns whether the service has started or not.
38pub(crate) fn condition_for_started() -> bool {
39    let event_db = event_db_is_live();
40    let index_db = index_db_is_live();
41    let follower =
42        live_follower_has_first_reached_tip() && immutable_follower_has_first_reached_tip();
43    debug!("Checking if service has started. Event DB: {event_db}, Index DB: {index_db}, Follower: {follower}");
44    event_db && index_db && follower
45}
46
47/// Returns whether the Event DB is live or not.
48///
49/// Gets the stored value from `LIVE_EVENT_DB` flag.
50pub(crate) fn event_db_is_live() -> bool {
51    LIVE_EVENT_DB.load(Acquire)
52}
53
54/// Set the `LIVE_EVENT_DB` flag.
55pub(crate) fn set_event_db_liveness(flag: bool) {
56    LIVE_EVENT_DB.store(flag, Release);
57}
58
59/// Returns whether the Index DB is live or not.
60///
61/// Gets the stored value from `LIVE_INDEX_DB` flag.
62pub(crate) fn index_db_is_live() -> bool {
63    LIVE_INDEX_DB.load(Acquire)
64}
65
66/// Set the `LIVE_INDEX_DB` flag.
67pub(crate) fn set_index_db_liveness(flag: bool) {
68    LIVE_INDEX_DB.store(flag, Release);
69}
70
71/// Returns whether the Chain Follower has reached Immutable Tip or not.
72///
73/// Gets the stored value from `INITIAL_IMMUTABLE_FOLLOWER_TIP_REACHED` flag.
74pub(crate) fn immutable_follower_has_first_reached_tip() -> bool {
75    INITIAL_IMMUTABLE_FOLLOWER_TIP_REACHED.load(Acquire)
76}
77
78/// Returns whether the Chain Follower has reached Live Tip or not.
79///
80/// Gets the stored value from `INITIAL_LIVE_FOLLOWER_TIP_REACHED` flag.
81pub(crate) fn live_follower_has_first_reached_tip() -> bool {
82    INITIAL_LIVE_FOLLOWER_TIP_REACHED.load(Acquire)
83}
84
85/// Set the `INITIAL_IMMUTABLE_FOLLOWER_TIP_REACHED` as `true`.
86/// returns the previous `INITIAL_IMMUTABLE_FOLLOWER_TIP_REACHED` value.
87///
88/// This value can not be set to `false` afterwards.
89pub(crate) fn set_follower_immutable_first_reached_tip() -> bool {
90    let prev_value = INITIAL_IMMUTABLE_FOLLOWER_TIP_REACHED.swap(true, Relaxed);
91    if !prev_value {
92        info!("Follower has reached IMMUTABLE TIP for the first time");
93    }
94    prev_value
95}
96
97/// Set the `INITIAL_LIVE_FOLLOWER_TIP_REACHED` as `true`,
98/// returns the previous `INITIAL_LIVE_FOLLOWER_TIP_REACHED` value.
99///
100/// This value can not be set to `false` afterwards.
101pub(crate) fn set_follower_live_first_reached_tip() -> bool {
102    let prev_value = INITIAL_LIVE_FOLLOWER_TIP_REACHED.swap(true, Relaxed);
103    if !prev_value {
104        info!("Follower has reached LIVE TIP for the first time");
105    }
106    prev_value
107}