Skip to content

Commit

Permalink
feat: introduce foyer-cli framework (#693)
Browse files Browse the repository at this point in the history
Signed-off-by: MrCroxx <[email protected]>
  • Loading branch information
MrCroxx authored Sep 9, 2024
1 parent fec88f0 commit 4d9be75
Show file tree
Hide file tree
Showing 7 changed files with 214 additions and 1 deletion.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ members = [
"examples",
"foyer",
"foyer-bench",
"foyer-cli",
"foyer-common",
"foyer-intrusive",
"foyer-memory",
Expand Down
3 changes: 2 additions & 1 deletion codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ coverage:
informational: true
only_pulls: true
ignore:
- "foyer-util"
- "foyer-util"
- "foyer-cli"
23 changes: 23 additions & 0 deletions foyer-cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[package]
name = "foyer-cli"
version = "0.0.0"
edition = "2021"
authors = ["MrCroxx <[email protected]>"]
description = "Hybrid cache for Rust"
license = "Apache-2.0"
repository = "https://github.com/foyer-rs/foyer"
homepage = "https://github.com/foyer-rs/foyer"
readme = "../README.md"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
anyhow = "1"
bytesize = "1"
clap = { workspace = true }
thiserror = "1"

[dev-dependencies]

[[bin]]
name = "foyer"
path = "src/main.rs"
32 changes: 32 additions & 0 deletions foyer-cli/src/args/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2024 Foyer Project Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::fmt::Debug;

/// Disk cache error type.
#[derive(thiserror::Error, Debug)]
pub enum Error {
/// I/O error.
#[error("io error: {0}")]
Io(#[from] std::io::Error),
/// `fio` not available.
#[error("fio not available")]
FioNotAvailable,
/// Other error.
#[error(transparent)]
Other(#[from] anyhow::Error),
}

/// Disk cache result type.
pub type Result<T> = core::result::Result<T, Error>;
67 changes: 67 additions & 0 deletions foyer-cli/src/args/fio.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Copyright 2024 Foyer Project Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::{collections::HashSet, process::Command};

use anyhow::anyhow;

use crate::args::error::{Error, Result};

type IoEngine = String;

#[derive(Debug)]
pub struct Fio {
io_engines: HashSet<IoEngine>,
}

impl Fio {
pub fn init() -> Result<Self> {
if !Self::available() {
return Err(Error::FioNotAvailable);
}

let io_engines = Self::list_io_engines()?;

Ok(Self { io_engines })
}

fn available() -> bool {
let output = match Command::new("fio").arg("--version").output() {
Ok(output) => output,
Err(_) => return false,
};
output.status.success()
}

pub fn io_engines(&self) -> &HashSet<IoEngine> {
&self.io_engines
}

fn list_io_engines() -> Result<HashSet<IoEngine>> {
let output = Command::new("fio").arg("--enghelp").output()?;
if !output.status.success() {
return Err(anyhow!("fail to get available io engines with fio").into());
}

let io_engines = String::from_utf8_lossy(&output.stdout)
.split('\n')
.skip(1)
.map(|s| s.trim())
.filter(|s| !s.is_empty())
.map(String::from)
.collect();

Ok(io_engines)
}
}
48 changes: 48 additions & 0 deletions foyer-cli/src/args/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright 2024 Foyer Project Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

mod error;
mod fio;

use bytesize::ByteSize;
use clap::{ArgGroup, Args};
use fio::Fio;

#[derive(Debug, Args)]
#[command(group = ArgGroup::new("exclusive").required(true).args(&["file", "dir"]))]
pub struct ArgsArgs {
/// File for disk cache data. Use `DirectFile` as device.
///
/// Either `file` or `dir` must be set.
#[arg(short, long)]
file: Option<String>,

/// Directory for disk cache data. Use `DirectFs` as device.
///
/// Either `file` or `dir` must be set.
#[arg(short, long)]
dir: Option<String>,

/// Size of the disk cache occupies.
#[arg(short, long)]
size: Option<ByteSize>,
}

pub fn run(args: ArgsArgs) {
println!("{args:#?}");

let fio = Fio::init().unwrap();

println!("{:#?}", fio.io_engines());
}
41 changes: 41 additions & 0 deletions foyer-cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright 2024 Foyer Project Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! `foyer-cli` provides debug tools for foyer,
mod args;

use args::ArgsArgs;
use clap::{Parser, Subcommand};

#[derive(Debug, Parser)]
#[command(author, version, about)]
pub struct Cli {
#[command(subcommand)]
command: Command,
}

#[derive(Debug, Subcommand)]
pub enum Command {
/// Automatic arguments detector.
Args(ArgsArgs),
}

fn main() {
let cli = Cli::parse();

match cli.command {
Command::Args(args) => args::run(args),
}
}

0 comments on commit 4d9be75

Please sign in to comment.