Skip to content

Commit

Permalink
Refactor client usage into edenfs-client
Browse files Browse the repository at this point in the history
Summary:
# Context

We are introducing EdenFS notifications to support scalable and ergonomic file system notifications for EdenFS mounts.

# This Diff

I noticed that we have a couple of patterns for how to integrate with EdenFS' Thrift API in our CLI code. I am choosing here to embrace capturing most (not quite all yet) of these details in the client library. This diff refactors some previous code to get journal position from  individual command to the library.

# Next Steps

Implement the `changes-since` command to `eden notify` then iterate on the `streamChangesSinceV2` Thrift endpoint.

# Discussion Points

None

Differential Revision: D65834704

fbshipit-source-id: 3af76bb4db698dd116dae41cdd5dea6d8d500a9f
  • Loading branch information
jdelliot authored and facebook-github-bot committed Nov 13, 2024
1 parent ada5411 commit d148c22
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 30 deletions.
21 changes: 21 additions & 0 deletions eden/fs/cli_rs/edenfs-client/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use edenfs_config::EdenFsConfig;
use edenfs_error::EdenFsError;
use edenfs_error::Result;
use edenfs_error::ResultExt;
use edenfs_utils::bytes_from_path;
use edenfs_utils::get_executable;
#[cfg(windows)]
use edenfs_utils::strip_unc_prefix;
Expand All @@ -34,6 +35,7 @@ use thrift_streaming_clients::errors::StreamStartStatusError;
#[cfg(fbcode_build)]
use thrift_streaming_thriftclients::build_StreamingEdenService_client;
use thrift_types::edenfs::DaemonInfo;
use thrift_types::edenfs::JournalPosition;
use thrift_types::edenfs_clients::EdenService;
use thrift_types::fb303_core::fb303_status;
use thrift_types::fbthrift::binary_protocol::BinaryProtocol;
Expand All @@ -47,6 +49,7 @@ use tracing::event;
use tracing::Level;
use util::lock::PathLock;

use crate::utils::get_mount_point;
use crate::EdenFsClient;
#[cfg(fbcode_build)]
use crate::StartStatusStream;
Expand Down Expand Up @@ -242,6 +245,24 @@ impl EdenFsInstance {
}
}

#[cfg(fbcode_build)]
pub async fn get_journal_position(
&self,
mount_point: &Option<PathBuf>,
timeout: Option<Duration>,
) -> Result<JournalPosition> {
let client = self
.connect(timeout)
.await
.context("Unable to connect to EdenFS daemon")?;
let mount_point_path = get_mount_point(mount_point)?;
let mount_point = bytes_from_path(mount_point_path)?;
client
.getCurrentJournalPosition(&mount_point)
.await
.from_err()
}

/// Returns a map of mount paths to mount names
/// as defined in EdenFS's config.json.
pub fn get_configured_mounts_map(&self) -> Result<BTreeMap<PathBuf, String>, anyhow::Error> {
Expand Down
1 change: 1 addition & 0 deletions eden/fs/cli_rs/edenfs-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub mod fsutil;
pub mod instance;
mod mounttable;
pub mod redirect;
pub mod utils;

pub use instance::DaemonHealthy;
pub use instance::EdenFsInstance;
Expand Down
31 changes: 31 additions & 0 deletions eden/fs/cli_rs/edenfs-client/src/utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This software may be used and distributed according to the terms of the
* GNU General Public License version 2.
*/

use std::path::Path;
use std::path::PathBuf;

use anyhow::anyhow;
use anyhow::Context;
use anyhow::Result;

/// Traverse up and locate the repository root
pub fn locate_repo_root(path: &Path) -> Option<&Path> {
path.ancestors()
.find(|p| p.join(".hg").is_dir() || p.join(".git").is_dir())
}

pub fn get_mount_point(mount_point: &Option<PathBuf>) -> Result<PathBuf> {
if let Some(path) = mount_point {
Ok(path.clone())
} else {
locate_repo_root(
&std::env::current_dir().context("Unable to retrieve current working directory")?,
)
.map(|p| p.to_path_buf())
.ok_or_else(|| anyhow!("Unable to locate repository root"))
}
}
2 changes: 1 addition & 1 deletion eden/fs/cli_rs/edenfs-commands/src/debug/subscribe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use anyhow::Context;
use anyhow::Result;
use async_trait::async_trait;
use clap::Parser;
use edenfs_client::utils::locate_repo_root;
use edenfs_client::EdenFsInstance;
use futures::StreamExt;
use hg_util::path::expand_path;
Expand All @@ -33,7 +34,6 @@ use tokio::sync::Notify;
use tokio::time;

use crate::util::jsonrpc::ResponseBuilder;
use crate::util::locate_repo_root;
use crate::ExitCode;

// Defines a few helper functions to make the debug format easier to read.
Expand Down
2 changes: 1 addition & 1 deletion eden/fs/cli_rs/edenfs-commands/src/notify/changes_since.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ use anyhow::Context;
use anyhow::Result;
use async_trait::async_trait;
use clap::Parser;
use edenfs_client::utils::locate_repo_root;
use edenfs_client::EdenFsInstance;
use edenfs_utils::bytes_from_path;
use hg_util::path::expand_path;

use crate::util::locate_repo_root;
use crate::ExitCode;

// TODO: add a --json flag to print the output in JSON format
Expand Down
25 changes: 3 additions & 22 deletions eden/fs/cli_rs/edenfs-commands/src/notify/get_position.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,12 @@

use std::path::PathBuf;

use anyhow::anyhow;
use anyhow::Context;
use anyhow::Result;
use async_trait::async_trait;
use clap::Parser;
use edenfs_client::EdenFsInstance;
use edenfs_utils::bytes_from_path;
use hg_util::path::expand_path;

use crate::util::locate_repo_root;
use crate::ExitCode;

// TODO: add a --json flag to print the output in JSON format
Expand All @@ -30,20 +26,6 @@ pub struct GetPositionCmd {
mount_point: Option<PathBuf>,
}

impl GetPositionCmd {
fn get_mount_point(&self) -> Result<PathBuf> {
if let Some(path) = &self.mount_point {
Ok(path.clone())
} else {
locate_repo_root(
&std::env::current_dir().context("Unable to retrieve current working directory")?,
)
.map(|p| p.to_path_buf())
.ok_or_else(|| anyhow!("Unable to locate repository root"))
}
}
}

#[async_trait]
impl crate::Subcommand for GetPositionCmd {
#[cfg(not(fbcode_build))]
Expand All @@ -55,10 +37,9 @@ impl crate::Subcommand for GetPositionCmd {
#[cfg(fbcode_build)]
async fn run(&self) -> Result<ExitCode> {
let instance = EdenFsInstance::global();
let client = instance.connect(None).await?;
let mount_point_path = self.get_mount_point()?;
let mount_point = bytes_from_path(mount_point_path)?;
let position = client.getCurrentJournalPosition(&mount_point).await?;
let position = instance
.get_journal_position(&self.mount_point, None)
.await?;
println!(
"{}:{}:{}",
position.mountGeneration,
Expand Down
6 changes: 0 additions & 6 deletions eden/fs/cli_rs/edenfs-commands/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,6 @@ pub fn remove_trailing_slash(path: &Path) -> PathBuf {
)
}

/// Traverse up and locate the repository root
pub fn locate_repo_root(path: &Path) -> Option<&Path> {
path.ancestors()
.find(|p| p.join(".hg").is_dir() || p.join(".git").is_dir())
}

pub fn locate_eden_config_dir(path: &Path) -> Option<PathBuf> {
// Check whether we're in an Eden mount. If we are, some parent directory will contain
// a .eden dir that contains a socket file. This socket file is symlinked to the
Expand Down

0 comments on commit d148c22

Please sign in to comment.