cli_rs: add pid command

Summary: This simply queries the pid from thrift.

Reviewed By: kmancini

Differential Revision: D26406797

fbshipit-source-id: 1d5d1b2d526e1de505d72747a5c903001b141d40
This commit is contained in:
Xavier Deguillard 2021-02-12 13:45:55 -08:00 committed by Facebook GitHub Bot
parent fdf2b69d6e
commit b63f46c673
5 changed files with 71 additions and 10 deletions

View File

@ -14,12 +14,13 @@ use std::time::Duration;
use anyhow::{anyhow, Context, Result}; use anyhow::{anyhow, Context, Result};
use tokio::net::UnixStream; use tokio::net::UnixStream;
use fb303_core::types::fb303_status;
use fbthrift_socket::SocketTransport; use fbthrift_socket::SocketTransport;
use thrift_types::edenfs::client::EdenService; use thrift_types::edenfs::{client::EdenService, types::DaemonInfo};
use thrift_types::fbthrift::binary_protocol::BinaryProtocol; use thrift_types::fbthrift::binary_protocol::BinaryProtocol;
use super::utils::get_executable; use crate::utils::get_executable;
use super::EdenFsClient; use crate::EdenFsClient;
#[derive(Debug)] #[derive(Debug)]
pub struct EdenFsInstance { pub struct EdenFsInstance {
@ -104,4 +105,20 @@ impl EdenFsInstance {
Err(anyhow!("EdenFS is not running")) Err(anyhow!("EdenFS is not running"))
} }
} }
pub async fn get_health(&self, timeout: Duration) -> Result<DaemonInfo> {
let client = self.connect(timeout).await?;
Ok(client.getDaemonInfo().await?)
}
}
pub trait DaemonHealthy {
fn is_healthy(&self) -> bool;
}
impl DaemonHealthy for DaemonInfo {
fn is_healthy(&self) -> bool {
self.status
.map_or_else(|| false, |val| val == fb303_status::ALIVE)
}
} }

View File

@ -12,6 +12,6 @@ use thrift_types::edenfs::client::EdenService;
pub mod instance; pub mod instance;
mod utils; mod utils;
pub use instance::EdenFsInstance; pub use instance::{DaemonHealthy, EdenFsInstance};
pub type EdenFsClient = Arc<dyn EdenService>; pub type EdenFsClient = Arc<dyn EdenService>;

View File

@ -15,6 +15,7 @@ use tracing::{event, Level};
use edenfs_client::EdenFsInstance; use edenfs_client::EdenFsInstance;
use util::path::expand_path; use util::path::expand_path;
mod pid;
mod status; mod status;
const DEFAULT_CONFIG_DIR: &str = "~/local/.eden"; const DEFAULT_CONFIG_DIR: &str = "~/local/.eden";
@ -58,6 +59,9 @@ pub enum SubCommand {
/// Check the health of the Eden service /// Check the health of the Eden service
#[structopt(alias = "health")] #[structopt(alias = "health")]
Status(crate::status::StatusCmd), Status(crate::status::StatusCmd),
/// Print the daemon's process ID if running
Pid(crate::pid::PidCmd),
} }
impl Command { impl Command {
@ -94,6 +98,7 @@ impl Command {
let instance = self.get_instance(); let instance = self.get_instance();
match self.subcommand { match self.subcommand {
SubCommand::Status(status) => status.run(instance).await, SubCommand::Status(status) => status.run(instance).await,
SubCommand::Pid(pid_cmd) => pid_cmd.run(instance).await,
} }
} }
} }

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This software may be used and distributed according to the terms of the
* GNU General Public License version 2.
*/
//! edenfsctl pid
use std::time::Duration;
use structopt::StructOpt;
use edenfs_client::EdenFsInstance;
use crate::ExitCode;
#[derive(StructOpt, Debug)]
pub struct PidCmd {
/// Wait up to TIMEOUT seconds for the daemon to respond
#[structopt(long, default_value = "3")]
timeout: u64,
}
impl PidCmd {
pub async fn run(self, instance: EdenFsInstance) -> ExitCode {
let health = instance.get_health(Duration::from_secs(self.timeout)).await;
match health {
Ok(health) => {
println!("{}", health.pid);
0
}
Err(cause) => {
println!("edenfs not healthy: {}", cause);
1
}
}
}
}

View File

@ -12,7 +12,7 @@ use std::time::Duration;
use anyhow::Result; use anyhow::Result;
use structopt::StructOpt; use structopt::StructOpt;
use edenfs_client::EdenFsInstance; use edenfs_client::{DaemonHealthy, EdenFsInstance};
use crate::ExitCode; use crate::ExitCode;
@ -25,12 +25,11 @@ pub struct StatusCmd {
impl StatusCmd { impl StatusCmd {
async fn get_status(&self, instance: &EdenFsInstance) -> Result<i32> { async fn get_status(&self, instance: &EdenFsInstance) -> Result<i32> {
let client = instance.connect(Duration::from_secs(self.timeout)).await; let health = instance.get_health(Duration::from_secs(self.timeout)).await;
if let Ok(client) = client { if let Ok(health) = health {
if let Ok(status) = client.getDaemonInfo().await { if health.is_healthy() {
// TODO: we should report health infomration from fb303 here return Ok(health.pid);
return Ok(status.pid);
} }
} }