1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// Copyright 2019-2024 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

use std::{
    io::{stdout, Write},
    time::Duration,
};

use crate::health::DEFAULT_HEALTHCHECK_PORT;
use crate::rpc;
use clap::Subcommand;
use http::StatusCode;
use ticker::Ticker;

#[derive(Debug, Subcommand)]
pub enum HealthcheckCommand {
    /// Display ready status
    Ready {
        /// Don't exit until node is ready
        #[arg(long)]
        wait: bool,
        /// Healthcheck port
        #[arg(long, default_value_t=DEFAULT_HEALTHCHECK_PORT)]
        healthcheck_port: u16,
    },
}

impl HealthcheckCommand {
    pub async fn run(self, client: rpc::Client) -> anyhow::Result<()> {
        match self {
            Self::Ready {
                wait,
                healthcheck_port,
            } => {
                let ticker = Ticker::new(0.., Duration::from_secs(1));
                let mut stdout = stdout();

                let url = format!(
                    "http://{}:{}/readyz?verbose",
                    client.base_url().host_str().unwrap_or("localhost"),
                    healthcheck_port,
                );

                for _ in ticker {
                    let response = reqwest::get(&url).await?;
                    let status = response.status();
                    let text = response.text().await?;

                    println!("{}", text);

                    if !wait {
                        break;
                    }
                    if status == StatusCode::OK {
                        println!("Done!");
                        break;
                    }

                    for _ in 0..(text.matches('\n').count() + 1) {
                        write!(
                            stdout,
                            "\r{}{}",
                            anes::MoveCursorUp(1),
                            anes::ClearLine::All,
                        )?;
                    }
                }
                Ok(())
            }
        }
    }
}