From eac5491db25aed380d6539e485d70a1cb1a79e1d Mon Sep 17 00:00:00 2001 From: Croxx Date: Wed, 21 Aug 2024 17:47:35 +0800 Subject: [PATCH 01/40] feat: support serde for more configs (#661) Signed-off-by: MrCroxx --- foyer-common/src/tracing.rs | 3 ++- foyer-storage/src/device/direct_file.rs | 3 ++- foyer-storage/src/device/direct_fs.rs | 3 ++- foyer-storage/src/store.rs | 3 +++ 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/foyer-common/src/tracing.rs b/foyer-common/src/tracing.rs index c57ad2fa..1c1ffbc9 100644 --- a/foyer-common/src/tracing.rs +++ b/foyer-common/src/tracing.rs @@ -13,6 +13,7 @@ // limitations under the License. use fastrace::prelude::*; +use serde::{Deserialize, Serialize}; use std::{ ops::Deref, @@ -26,7 +27,7 @@ use futures::{ready, Future}; use pin_project::pin_project; /// Configurations for tracing. -#[derive(Debug)] +#[derive(Debug, Serialize, Deserialize)] pub struct TracingConfig { /// Threshold for recording the hybrid cache `insert` and `insert_with_context` operation in us. record_hybrid_insert_threshold_us: AtomicUsize, diff --git a/foyer-storage/src/device/direct_file.rs b/foyer-storage/src/device/direct_file.rs index 2f08171e..d67ea422 100644 --- a/foyer-storage/src/device/direct_file.rs +++ b/foyer-storage/src/device/direct_file.rs @@ -13,6 +13,7 @@ // limitations under the License. use foyer_common::{asyncify::asyncify_with_runtime, bits, fs::freespace}; +use serde::{Deserialize, Serialize}; use tokio::runtime::Handle; use super::{Dev, DevExt, DevOptions, RegionId}; @@ -28,7 +29,7 @@ use std::{ }; /// Options for the direct file device. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct DirectFileDeviceOptions { /// Path of the direct file device. pub path: PathBuf, diff --git a/foyer-storage/src/device/direct_fs.rs b/foyer-storage/src/device/direct_fs.rs index a8c30a5e..c8f50329 100644 --- a/foyer-storage/src/device/direct_fs.rs +++ b/foyer-storage/src/device/direct_fs.rs @@ -21,6 +21,7 @@ use std::{ use foyer_common::{asyncify::asyncify_with_runtime, bits, fs::freespace}; use futures::future::try_join_all; use itertools::Itertools; +use serde::{Deserialize, Serialize}; use tokio::runtime::Handle; use super::{Dev, DevExt, DevOptions, RegionId}; @@ -31,7 +32,7 @@ use crate::{ }; /// Options for the direct fs device. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct DirectFsDeviceOptions { /// Directory of the direct fs device. pub dir: PathBuf, diff --git a/foyer-storage/src/store.rs b/foyer-storage/src/store.rs index 6bfacfdd..dcccd1ae 100644 --- a/foyer-storage/src/store.rs +++ b/foyer-storage/src/store.rs @@ -42,6 +42,7 @@ use foyer_common::{ runtime::BackgroundShutdownRuntime, }; use foyer_memory::{Cache, CacheEntry}; +use serde::{Deserialize, Serialize}; use std::{borrow::Borrow, fmt::Debug, hash::Hash, marker::PhantomData, sync::Arc, time::Instant}; use tokio::runtime::Handle; @@ -287,6 +288,7 @@ impl CombinedConfig { } /// Tokio runtime configuration. +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct TokioRuntimeConfig { /// Dedicated runtime worker threads. /// @@ -305,6 +307,7 @@ pub struct TokioRuntimeConfig { } /// Configuration for the dedicated runtime. +#[derive(Debug, Clone, Serialize, Deserialize)] pub enum RuntimeConfig { /// Disable dedicated runtime. The runtime which foyer is built on will be used. Disabled, From bac9002f4874e013639976197d1f9d778d913b30 Mon Sep 17 00:00:00 2001 From: Croxx Date: Wed, 21 Aug 2024 18:24:45 +0800 Subject: [PATCH 02/40] refactor: expose Weighter trait (#662) Signed-off-by: MrCroxx --- foyer/src/prelude.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/foyer/src/prelude.rs b/foyer/src/prelude.rs index d0f20768..06dc78d1 100644 --- a/foyer/src/prelude.rs +++ b/foyer/src/prelude.rs @@ -25,7 +25,7 @@ pub use common::{ range::RangeBoundsExt, tracing::TracingConfig, }; -pub use memory::{CacheContext, EvictionConfig, FetchState, FifoConfig, LfuConfig, LruConfig, S3FifoConfig}; +pub use memory::{CacheContext, EvictionConfig, FetchState, FifoConfig, LfuConfig, LruConfig, S3FifoConfig, Weighter}; pub use storage::{ AdmissionPicker, AdmitAllPicker, Compression, Dev, DevExt, DevOptions, DeviceStats, DirectFileDevice, DirectFileDeviceOptions, DirectFileDeviceOptionsBuilder, DirectFsDevice, DirectFsDeviceOptions, From 47355261f55cfd400d46b8cfec57874d15a3a62d Mon Sep 17 00:00:00 2001 From: Croxx Date: Wed, 21 Aug 2024 18:45:19 +0800 Subject: [PATCH 03/40] chore: release foyer 0.11.0 (#663) * chore: release foyer 0.11.0 Signed-off-by: MrCroxx * chore: update change log and ci cache key Signed-off-by: MrCroxx --------- Signed-off-by: MrCroxx --- .github/template/template.yml | 2 +- .github/workflows/main.yml | 2 +- .github/workflows/pull-request.yml | 2 +- CHANGELOG.md | 26 ++++++++++++++++++++++++++ README.md | 22 +++++++++++++--------- foyer-bench/Cargo.toml | 4 ++-- foyer-common/Cargo.toml | 2 +- foyer-intrusive/Cargo.toml | 4 ++-- foyer-memory/Cargo.toml | 6 +++--- foyer-storage/Cargo.toml | 6 +++--- foyer/Cargo.toml | 8 ++++---- 11 files changed, 57 insertions(+), 27 deletions(-) diff --git a/.github/template/template.yml b/.github/template/template.yml index 92854f58..bd69a0e6 100644 --- a/.github/template/template.yml +++ b/.github/template/template.yml @@ -5,7 +5,7 @@ on: env: RUST_TOOLCHAIN_NIGHTLY: nightly-2024-03-17 CARGO_TERM_COLOR: always - CACHE_KEY_SUFFIX: 20240621 + CACHE_KEY_SUFFIX: 20240821 jobs: misc-check: diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 55bed569..a4d967eb 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -13,7 +13,7 @@ on: env: RUST_TOOLCHAIN_NIGHTLY: nightly-2024-03-17 CARGO_TERM_COLOR: always - CACHE_KEY_SUFFIX: 20240621 + CACHE_KEY_SUFFIX: 20240821 jobs: misc-check: name: misc check diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index b336e352..abc9a0d7 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -12,7 +12,7 @@ on: env: RUST_TOOLCHAIN_NIGHTLY: nightly-2024-03-17 CARGO_TERM_COLOR: always - CACHE_KEY_SUFFIX: 20240621 + CACHE_KEY_SUFFIX: 20240821 jobs: misc-check: name: misc check diff --git a/CHANGELOG.md b/CHANGELOG.md index 245a4e0b..4f8a355b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,29 @@ +## 2024-08-21 + +| crate | version | +| - | - | +| foyer | 0.11.0 | +| foyer-common | 0.9.0 | +| foyer-intrusive | 0.9.0 | +| foyer-memory | 0.7.0 | +| foyer-storage | 0.10.0 | +| foyer-bench | 0.3.0 | + +
+ +### Changes + +- Support disk cache on raw block device. +- Support fine-grained storage engine runtime configuration. +- Enhance performance via reducing page fault. +- Refine storage engine framework for future features. +- Expose `Weighter` trait. +- Support `serde` for more configurations. +- Update `foyer-bench` with more fine-grained configurations. +- Fix panices with `None` recover mode. + +
+ ## 2024-08-15 | crate | version | diff --git a/README.md b/README.md index 815b0358..587f3872 100644 --- a/README.md +++ b/README.md @@ -39,13 +39,13 @@ Feel free to open a PR and add your projects here: To use *foyer* in your project, add this line to the `dependencies` section of `Cargo.toml`. ```toml -foyer = "0.10" +foyer = "0.11" ``` If your project is using the nightly rust toolchain, the `nightly` feature needs to be enabled. ```toml -foyer = { version = "0.10", features = ["nightly"] } +foyer = { version = "0.11", features = ["nightly"] } ``` ### Out-of-the-box In-memory Cache @@ -102,7 +102,7 @@ use anyhow::Result; use chrono::Datelike; use foyer::{ DirectFsDeviceOptionsBuilder, FifoPicker, HybridCache, HybridCacheBuilder, LruConfig, RateLimitPicker, RecoverMode, - RuntimeConfigBuilder, TombstoneLogConfigBuilder, + RuntimeConfig, TokioRuntimeConfig, TombstoneLogConfigBuilder, }; use tempfile::tempdir; @@ -143,12 +143,16 @@ async fn main() -> Result<()> { .with_flush(true) .build(), ) - .with_runtime_config( - RuntimeConfigBuilder::new() - .with_thread_name("foyer") - .with_worker_threads(4) - .build(), - ) + .with_runtime_config(RuntimeConfig::Separated { + read_runtime_config: TokioRuntimeConfig { + worker_threads: 4, + max_blocking_threads: 8, + }, + write_runtime_config: TokioRuntimeConfig { + worker_threads: 4, + max_blocking_threads: 8, + }, + }) .build() .await?; diff --git a/foyer-bench/Cargo.toml b/foyer-bench/Cargo.toml index f9cd01af..1b8304b8 100644 --- a/foyer-bench/Cargo.toml +++ b/foyer-bench/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "foyer-bench" -version = "0.2.3" +version = "0.3.0" edition = "2021" authors = ["MrCroxx "] description = "bench tool for foyer - the hybrid cache for Rust" @@ -17,7 +17,7 @@ clap = { workspace = true } console-subscriber = { version = "0.4", optional = true } fastrace = { workspace = true, optional = true } fastrace-jaeger = { workspace = true, optional = true } -foyer = { version = "0.10.4", path = "../foyer" } +foyer = { version = "0.11.0", path = "../foyer" } futures = "0.3" hdrhistogram = "7" itertools = { workspace = true } diff --git a/foyer-common/Cargo.toml b/foyer-common/Cargo.toml index 4ae2a261..44ae7422 100644 --- a/foyer-common/Cargo.toml +++ b/foyer-common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "foyer-common" -version = "0.8.1" +version = "0.9.0" edition = "2021" authors = ["MrCroxx "] description = "common components for foyer - the hybrid cache for Rust" diff --git a/foyer-intrusive/Cargo.toml b/foyer-intrusive/Cargo.toml index ab44037e..cbcfc837 100644 --- a/foyer-intrusive/Cargo.toml +++ b/foyer-intrusive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "foyer-intrusive" -version = "0.8.1" +version = "0.9.0" edition = "2021" authors = ["MrCroxx "] description = "intrusive data structures for foyer - the hybrid cache for Rust" @@ -11,7 +11,7 @@ readme = "../README.md" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -foyer-common = { version = "0.8.1", path = "../foyer-common" } +foyer-common = { version = "0.9.0", path = "../foyer-common" } itertools = { workspace = true } [features] diff --git a/foyer-memory/Cargo.toml b/foyer-memory/Cargo.toml index fa7828e0..7ed46d0e 100644 --- a/foyer-memory/Cargo.toml +++ b/foyer-memory/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "foyer-memory" -version = "0.6.1" +version = "0.7.0" edition = "2021" authors = ["MrCroxx "] description = "memory cache for foyer - the hybrid cache for Rust" @@ -15,8 +15,8 @@ ahash = "0.8" bitflags = "2" cmsketch = "0.2.1" fastrace = { workspace = true } -foyer-common = { version = "0.8.1", path = "../foyer-common" } -foyer-intrusive = { version = "0.8.1", path = "../foyer-intrusive" } +foyer-common = { version = "0.9.0", path = "../foyer-common" } +foyer-intrusive = { version = "0.9.0", path = "../foyer-intrusive" } futures = "0.3" hashbrown = "0.14" itertools = { workspace = true } diff --git a/foyer-storage/Cargo.toml b/foyer-storage/Cargo.toml index 69d4c299..bb37deb5 100644 --- a/foyer-storage/Cargo.toml +++ b/foyer-storage/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "foyer-storage" -version = "0.9.3" +version = "0.10.0" edition = "2021" authors = ["MrCroxx "] description = "storage engine for foyer - the hybrid cache for Rust" @@ -24,8 +24,8 @@ bytes = "1" clap = { workspace = true } either = "1" fastrace = { workspace = true } -foyer-common = { version = "0.8.1", path = "../foyer-common" } -foyer-memory = { version = "0.6.1", path = "../foyer-memory" } +foyer-common = { version = "0.9.0", path = "../foyer-common" } +foyer-memory = { version = "0.7.0", path = "../foyer-memory" } futures = "0.3" itertools = { workspace = true } lazy_static = "1" diff --git a/foyer/Cargo.toml b/foyer/Cargo.toml index 2d114c72..126b5692 100644 --- a/foyer/Cargo.toml +++ b/foyer/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "foyer" -version = "0.10.4" +version = "0.11.0" edition = "2021" authors = ["MrCroxx "] description = "Hybrid cache for Rust" @@ -15,9 +15,9 @@ rust-version = "1.77" ahash = "0.8" anyhow = "1" fastrace = { workspace = true } -foyer-common = { version = "0.8.1", path = "../foyer-common" } -foyer-memory = { version = "0.6.1", path = "../foyer-memory" } -foyer-storage = { version = "0.9.3", path = "../foyer-storage" } +foyer-common = { version = "0.9.0", path = "../foyer-common" } +foyer-memory = { version = "0.7.0", path = "../foyer-memory" } +foyer-storage = { version = "0.10.0", path = "../foyer-storage" } futures = "0.3" pin-project = "1" tokio = { workspace = true } From 0e9663816eb69bf64aaf703d226f3b0a0d541a52 Mon Sep 17 00:00:00 2001 From: Croxx Date: Thu, 22 Aug 2024 01:26:52 +0800 Subject: [PATCH 04/40] feat: introduce metrics for serde (#666) Signed-off-by: MrCroxx --- etc/grafana/dashboards/foyer.json | 2 +- foyer-bench/Cargo.toml | 2 +- foyer-common/src/metrics.rs | 9 +++++++++ foyer-storage/src/large/generic.rs | 14 ++++++++++++-- foyer-storage/src/large/reclaimer.rs | 11 +++++++++-- foyer-storage/src/large/recover.rs | 11 ++++++++--- foyer-storage/src/large/scanner.rs | 8 +++++++- foyer-storage/src/serde.rs | 17 +++++++++++++++-- foyer-storage/src/store.rs | 8 +++++++- foyer-storage/src/test_utils.rs | 19 +++++++++++++++++-- 10 files changed, 86 insertions(+), 15 deletions(-) diff --git a/etc/grafana/dashboards/foyer.json b/etc/grafana/dashboards/foyer.json index c2d22cc0..de81fb91 100644 --- a/etc/grafana/dashboards/foyer.json +++ b/etc/grafana/dashboards/foyer.json @@ -1 +1 @@ -{"annotations":{"list":[{"builtIn":1,"datasource":{"type":"grafana","uid":"-- Grafana --"},"enable":true,"hide":true,"iconColor":"rgba(0, 211, 255, 1)","name":"Annotations & Alerts","type":"dashboard"}]},"editable":true,"fiscalYearStartMonth":0,"graphTooltip":1,"links":[],"liveNow":false,"panels":[{"gridPos":{"h":1,"w":24,"x":0,"y":0},"id":22,"title":"Hybrid","type":"row"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisBorderShow":false,"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"ops"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":1},"id":23,"options":{"legend":{"calcs":["lastNotNull"],"displayMode":"table","placement":"bottom","showLegend":true},"tooltip":{"maxHeight":600,"mode":"multi","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"sum(rate(foyer_hybrid_op_total[$__rate_interval])) by (name, op)","instant":false,"legendFormat":"{{name}} - hybrid - {{op}}","range":true,"refId":"A"}],"title":"Op","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisBorderShow":false,"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"s"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":1},"id":24,"options":{"legend":{"calcs":["lastNotNull"],"displayMode":"table","placement":"bottom","showLegend":true},"tooltip":{"maxHeight":600,"mode":"multi","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(0.5, sum(rate(foyer_hybrid_op_duration_bucket[$__rate_interval])) by (le, name, op)) ","instant":false,"legendFormat":"p50 - {{name}} - hybrid - {{op}}","range":true,"refId":"A"},{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(0.9, sum(rate(foyer_hybrid_op_duration_bucket[$__rate_interval])) by (le, name, op)) ","hide":false,"instant":false,"legendFormat":"p90 - {{name}} - hybrid - {{op}}","range":true,"refId":"B"},{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(0.99, sum(rate(foyer_hybrid_op_duration_bucket[$__rate_interval])) by (le, name, op)) ","hide":false,"instant":false,"legendFormat":"p99 - {{name}} - hybrid - {{op}}","range":true,"refId":"C"},{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(1.0, sum(rate(foyer_hybrid_op_duration_bucket[$__rate_interval])) by (le, name, op)) ","hide":false,"instant":false,"legendFormat":"pmax - {{name}} - hybrid - {{op}}","range":true,"refId":"D"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"editorMode":"code","expr":"sum(rate(foyer_hybrid_op_duration_sum[$__rate_interval])) by (le, name, op) / sum(rate(foyer_hybrid_op_duration_count[$__rate_interval])) by (le, name, op)","hide":false,"instant":false,"legendFormat":"pavg - {{name}} - hybrid - {{op}}","range":true,"refId":"E"}],"title":"Op Duration","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisBorderShow":false,"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"percentunit"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":9},"id":25,"options":{"legend":{"calcs":["lastNotNull"],"displayMode":"table","placement":"bottom","showLegend":true},"tooltip":{"maxHeight":600,"mode":"multi","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"sum(rate(foyer_hybrid_op_total{op=\"hit\"}[$__rate_interval])) by (name) / (sum(rate(foyer_hybrid_op_total{op=\"hit\"}[$__rate_interval])) by (name) + sum(rate(foyer_hybrid_op_total{op=\"miss\"}[$__rate_interval])) by (name)) ","instant":false,"legendFormat":"{{name}} - hybrid - hit ratio","range":true,"refId":"A"}],"title":"Hit Ratio","type":"timeseries"},{"gridPos":{"h":1,"w":24,"x":0,"y":17},"id":14,"title":"Memory","type":"row"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisBorderShow":false,"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"ops"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":18},"id":13,"options":{"legend":{"calcs":["lastNotNull"],"displayMode":"table","placement":"bottom","showLegend":true},"tooltip":{"maxHeight":600,"mode":"multi","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"sum(rate(foyer_memory_op_total[$__rate_interval])) by (name, op)","instant":false,"legendFormat":"{{name}} - memory - {{op}}","range":true,"refId":"A"}],"title":"Op","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisBorderShow":false,"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"decbytes"},"overrides":[{"matcher":{"id":"byFrameRefID","options":"B"},"properties":[{"id":"unit"}]}]},"gridPos":{"h":8,"w":12,"x":12,"y":18},"id":15,"options":{"legend":{"calcs":["lastNotNull"],"displayMode":"table","placement":"bottom","showLegend":true},"tooltip":{"maxHeight":600,"mode":"multi","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"sum(foyer_memory_usage) by (name)","instant":false,"legendFormat":"{{name}} - memory - usage (bytes)","range":true,"refId":"A"},{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"sum(foyer_memory_usage) by (name)","hide":true,"instant":false,"legendFormat":"{{name}} - memory - usage (count)","range":true,"refId":"B"}],"title":"Usage","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisBorderShow":false,"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"percentunit"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":26},"id":7,"options":{"legend":{"calcs":["lastNotNull"],"displayMode":"table","placement":"bottom","showLegend":true},"tooltip":{"maxHeight":600,"mode":"multi","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"sum(rate(foyer_memory_op_total{op=\"hit\"}[$__rate_interval])) by (name) / (sum(rate(foyer_memory_op_total{op=\"hit\"}[$__rate_interval])) by (name) + sum(rate(foyer_memory_op_total{op=\"miss\"}[$__rate_interval])) by (name)) ","instant":false,"legendFormat":"{{name}} - memory - hit ratio","range":true,"refId":"A"}],"title":"Hit Ratio","type":"timeseries"},{"collapsed":false,"gridPos":{"h":1,"w":24,"x":0,"y":34},"id":8,"panels":[],"title":"Storage","type":"row"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisBorderShow":false,"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"ops"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":35},"id":1,"options":{"legend":{"calcs":["lastNotNull"],"displayMode":"table","placement":"bottom","showLegend":true},"tooltip":{"maxHeight":600,"mode":"multi","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"sum(rate(foyer_storage_op_total[$__rate_interval])) by (name, op)","instant":false,"legendFormat":"{{name}} - storage - {{op}}","range":true,"refId":"A"}],"title":"Op","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisBorderShow":false,"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"ops"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":35},"id":2,"options":{"legend":{"calcs":["lastNotNull"],"displayMode":"table","placement":"bottom","showLegend":true},"tooltip":{"maxHeight":600,"mode":"multi","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"sum(rate(foyer_storage_inner_op_total[$__rate_interval])) by (name, op)","instant":false,"legendFormat":"{{name}} - storage - {{op}}","range":true,"refId":"A"}],"title":"Inner Op","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisBorderShow":false,"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"s"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":43},"id":16,"options":{"legend":{"calcs":["lastNotNull"],"displayMode":"table","placement":"bottom","showLegend":true},"tooltip":{"maxHeight":600,"mode":"multi","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(0.5, sum(rate(foyer_storage_op_duration_bucket[$__rate_interval])) by (le, name, op)) ","instant":false,"legendFormat":"p50 - {{name}} - storage - {{op}}","range":true,"refId":"A"},{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(0.9, sum(rate(foyer_storage_op_duration_bucket[$__rate_interval])) by (le, name, op)) ","hide":false,"instant":false,"legendFormat":"p90 - {{name}} - storage - {{op}}","range":true,"refId":"B"},{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(0.99, sum(rate(foyer_storage_op_duration_bucket[$__rate_interval])) by (le, name, op)) ","hide":false,"instant":false,"legendFormat":"p99 - {{name}} - storage - {{op}}","range":true,"refId":"C"},{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(1.0, sum(rate(foyer_storage_op_duration_bucket[$__rate_interval])) by (le, name, op)) ","hide":false,"instant":false,"legendFormat":"pmax - {{name}} - storage - {{op}}","range":true,"refId":"D"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"editorMode":"code","expr":"sum(rate(foyer_storage_op_duration_sum[$__rate_interval])) by (le, name, op) / sum(rate(foyer_storage_op_duration_count[$__rate_interval])) by (le, name, op)","hide":false,"instant":false,"legendFormat":"pavg - {{name}} - storage - {{op}}","range":true,"refId":"E"}],"title":"Op Duration","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisBorderShow":false,"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"s"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":43},"id":17,"options":{"legend":{"calcs":["lastNotNull"],"displayMode":"table","placement":"bottom","showLegend":true},"tooltip":{"maxHeight":600,"mode":"multi","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(0.5, sum(rate(foyer_storage_inner_op_duration_bucket[$__rate_interval])) by (le, name, op)) ","instant":false,"legendFormat":"p50 - {{name}} - storage - {{op}}","range":true,"refId":"A"},{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(0.9, sum(rate(foyer_storage_inner_op_duration_bucket[$__rate_interval])) by (le, name, op)) ","hide":false,"instant":false,"legendFormat":"p90 - {{name}} - storage - {{op}}","range":true,"refId":"B"},{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(0.99, sum(rate(foyer_storage_inner_op_duration_bucket[$__rate_interval])) by (le, name, op)) ","hide":false,"instant":false,"legendFormat":"p99 - {{name}} - storage - {{op}}","range":true,"refId":"C"},{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(1.0, sum(rate(foyer_storage_inner_op_duration_bucket[$__rate_interval])) by (le, name, op)) ","hide":false,"instant":false,"legendFormat":"pmax - {{name}} - storage - {{op}}","range":true,"refId":"D"},{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"sum(rate(foyer_storage_inner_op_duration_sum[$__rate_interval])) by (le, name, op) / sum(rate(foyer_storage_inner_op_duration_count[$__rate_interval])) by (le, name, op)","hide":false,"instant":false,"legendFormat":"pavg - {{name}} - storage - {{op}}","range":true,"refId":"E"}],"title":"Inner Op Duration","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisBorderShow":false,"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]}},"overrides":[{"matcher":{"id":"byFrameRefID","options":"B"},"properties":[{"id":"unit"}]}]},"gridPos":{"h":8,"w":12,"x":0,"y":51},"id":27,"options":{"legend":{"calcs":["lastNotNull"],"displayMode":"table","placement":"bottom","showLegend":true},"tooltip":{"maxHeight":600,"mode":"multi","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"sum(foyer_storage_region) by (name, type)","instant":false,"legendFormat":"{{name}} - region - {{type}}","range":true,"refId":"A"}],"title":"Region Count","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisBorderShow":false,"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"decbytes"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":51},"id":28,"options":{"legend":{"calcs":["lastNotNull"],"displayMode":"table","placement":"bottom","showLegend":true},"tooltip":{"maxHeight":600,"mode":"multi","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"sum(foyer_storage_region) by (name, type) * on(name) group_left() foyer_storage_region_size_bytes","instant":false,"legendFormat":"{{name}} - region - {{type}}","range":true,"refId":"A"}],"title":"Region Size","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisBorderShow":false,"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"percentunit"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":59},"id":18,"options":{"legend":{"calcs":["lastNotNull"],"displayMode":"table","placement":"bottom","showLegend":true},"tooltip":{"maxHeight":600,"mode":"multi","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"sum(rate(foyer_storage_op_total{op=\"hit\"}[$__rate_interval])) by (name) / (sum(rate(foyer_storage_op_total{op=\"hit\"}[$__rate_interval])) by (name) + sum(rate(foyer_storage_op_total{op=\"miss\"}[$__rate_interval])) by (name)) ","instant":false,"legendFormat":"{{name}} - storage - hit ratio","range":true,"refId":"A"}],"title":"Hit Ratio","type":"timeseries"},{"collapsed":false,"gridPos":{"h":1,"w":24,"x":0,"y":67},"id":19,"panels":[],"title":"Storage (Disk)","type":"row"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisBorderShow":false,"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"ops"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":68},"id":20,"options":{"legend":{"calcs":["lastNotNull"],"displayMode":"table","placement":"bottom","showLegend":true},"tooltip":{"maxHeight":600,"mode":"multi","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"sum(rate(foyer_storage_disk_io_total[$__rate_interval])) by (name, op)","instant":false,"legendFormat":"{{name}} - disk io - {{op}}","range":true,"refId":"A"}],"title":"Disk IO","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisBorderShow":false,"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"s"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":68},"id":21,"options":{"legend":{"calcs":["lastNotNull"],"displayMode":"table","placement":"bottom","showLegend":true},"tooltip":{"maxHeight":600,"mode":"multi","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(0.5, sum(rate(foyer_storage_disk_io_duration_bucket[$__rate_interval])) by (le, name, op)) ","instant":false,"legendFormat":"p50 - {{name}} - disk io - {{op}}","range":true,"refId":"A"},{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(0.9, sum(rate(foyer_storage_disk_io_duration_bucket[$__rate_interval])) by (le, name, op)) ","hide":false,"instant":false,"legendFormat":"p90 - {{name}} - disk io - {{op}}","range":true,"refId":"B"},{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(0.99, sum(rate(foyer_storage_disk_io_duration_bucket[$__rate_interval])) by (le, name, op)) ","hide":false,"instant":false,"legendFormat":"p99 - {{name}} - disk io - {{op}}","range":true,"refId":"C"},{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(1.0, sum(rate(foyer_storage_disk_io_duration_bucket[$__rate_interval])) by (le, name, op)) ","hide":false,"instant":false,"legendFormat":"pmax - {{name}} - disk io - {{op}}","range":true,"refId":"D"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"editorMode":"code","expr":"sum(rate(foyer_storage_disk_io_duration_sum[$__rate_interval])) by (le, name, op) / sum(rate(foyer_storage_disk_io_duration_count[$__rate_interval])) by (le, name, op)","hide":false,"instant":false,"legendFormat":"pavg - {{name}} - disk io - {{op}}","range":true,"refId":"E"}],"title":"Disk IO Duration","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisBorderShow":false,"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"Bps"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":76},"id":5,"options":{"legend":{"calcs":["lastNotNull"],"displayMode":"table","placement":"bottom","showLegend":true},"tooltip":{"maxHeight":600,"mode":"multi","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"sum(rate(foyer_storage_disk_io_bytes[$__rate_interval])) by (foyer, op, extra) ","instant":false,"legendFormat":"{{foyer}} foyer storage - {{op}} {{extra}}","range":true,"refId":"A"}],"title":"Op Thoughput","type":"timeseries"}],"refresh":"5s","schemaVersion":39,"tags":[],"templating":{"list":[]},"time":{"from":"now-30m","to":"now"},"timeRangeUpdatedDuringEditOrView":false,"timepicker":{},"timezone":"","title":"foyer","uid":"f0e2058b-b292-457c-8ddf-9dbdf7c60035","version":1,"weekStart":""} +{"annotations":{"list":[{"builtIn":1,"datasource":{"type":"grafana","uid":"-- Grafana --"},"enable":true,"hide":true,"iconColor":"rgba(0, 211, 255, 1)","name":"Annotations & Alerts","type":"dashboard"}]},"editable":true,"fiscalYearStartMonth":0,"graphTooltip":1,"links":[],"liveNow":false,"panels":[{"gridPos":{"h":1,"w":24,"x":0,"y":0},"id":22,"title":"Hybrid","type":"row"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisBorderShow":false,"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"ops"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":1},"id":23,"options":{"legend":{"calcs":["lastNotNull"],"displayMode":"table","placement":"bottom","showLegend":true},"tooltip":{"maxHeight":600,"mode":"multi","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"sum(rate(foyer_hybrid_op_total[$__rate_interval])) by (name, op)","instant":false,"legendFormat":"{{name}} - hybrid - {{op}}","range":true,"refId":"A"}],"title":"Op","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisBorderShow":false,"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"s"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":1},"id":24,"options":{"legend":{"calcs":["lastNotNull"],"displayMode":"table","placement":"bottom","showLegend":true},"tooltip":{"maxHeight":600,"mode":"multi","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(0.5, sum(rate(foyer_hybrid_op_duration_bucket[$__rate_interval])) by (le, name, op)) ","instant":false,"legendFormat":"p50 - {{name}} - hybrid - {{op}}","range":true,"refId":"A"},{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(0.9, sum(rate(foyer_hybrid_op_duration_bucket[$__rate_interval])) by (le, name, op)) ","hide":false,"instant":false,"legendFormat":"p90 - {{name}} - hybrid - {{op}}","range":true,"refId":"B"},{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(0.99, sum(rate(foyer_hybrid_op_duration_bucket[$__rate_interval])) by (le, name, op)) ","hide":false,"instant":false,"legendFormat":"p99 - {{name}} - hybrid - {{op}}","range":true,"refId":"C"},{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(1.0, sum(rate(foyer_hybrid_op_duration_bucket[$__rate_interval])) by (le, name, op)) ","hide":false,"instant":false,"legendFormat":"pmax - {{name}} - hybrid - {{op}}","range":true,"refId":"D"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"editorMode":"code","expr":"sum(rate(foyer_hybrid_op_duration_sum[$__rate_interval])) by (le, name, op) / sum(rate(foyer_hybrid_op_duration_count[$__rate_interval])) by (le, name, op)","hide":false,"instant":false,"legendFormat":"pavg - {{name}} - hybrid - {{op}}","range":true,"refId":"E"}],"title":"Op Duration","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisBorderShow":false,"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"percentunit"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":9},"id":25,"options":{"legend":{"calcs":["lastNotNull"],"displayMode":"table","placement":"bottom","showLegend":true},"tooltip":{"maxHeight":600,"mode":"multi","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"sum(rate(foyer_hybrid_op_total{op=\"hit\"}[$__rate_interval])) by (name) / (sum(rate(foyer_hybrid_op_total{op=\"hit\"}[$__rate_interval])) by (name) + sum(rate(foyer_hybrid_op_total{op=\"miss\"}[$__rate_interval])) by (name)) ","instant":false,"legendFormat":"{{name}} - hybrid - hit ratio","range":true,"refId":"A"}],"title":"Hit Ratio","type":"timeseries"},{"gridPos":{"h":1,"w":24,"x":0,"y":17},"id":14,"title":"Memory","type":"row"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisBorderShow":false,"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"ops"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":18},"id":13,"options":{"legend":{"calcs":["lastNotNull"],"displayMode":"table","placement":"bottom","showLegend":true},"tooltip":{"maxHeight":600,"mode":"multi","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"sum(rate(foyer_memory_op_total[$__rate_interval])) by (name, op)","instant":false,"legendFormat":"{{name}} - memory - {{op}}","range":true,"refId":"A"}],"title":"Op","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisBorderShow":false,"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"decbytes"},"overrides":[{"matcher":{"id":"byFrameRefID","options":"B"},"properties":[{"id":"unit"}]}]},"gridPos":{"h":8,"w":12,"x":12,"y":18},"id":15,"options":{"legend":{"calcs":["lastNotNull"],"displayMode":"table","placement":"bottom","showLegend":true},"tooltip":{"maxHeight":600,"mode":"multi","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"sum(foyer_memory_usage) by (name)","instant":false,"legendFormat":"{{name}} - memory - usage (bytes)","range":true,"refId":"A"},{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"sum(foyer_memory_usage) by (name)","hide":true,"instant":false,"legendFormat":"{{name}} - memory - usage (count)","range":true,"refId":"B"}],"title":"Usage","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisBorderShow":false,"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"percentunit"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":26},"id":7,"options":{"legend":{"calcs":["lastNotNull"],"displayMode":"table","placement":"bottom","showLegend":true},"tooltip":{"maxHeight":600,"mode":"multi","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"sum(rate(foyer_memory_op_total{op=\"hit\"}[$__rate_interval])) by (name) / (sum(rate(foyer_memory_op_total{op=\"hit\"}[$__rate_interval])) by (name) + sum(rate(foyer_memory_op_total{op=\"miss\"}[$__rate_interval])) by (name)) ","instant":false,"legendFormat":"{{name}} - memory - hit ratio","range":true,"refId":"A"}],"title":"Hit Ratio","type":"timeseries"},{"collapsed":false,"gridPos":{"h":1,"w":24,"x":0,"y":34},"id":8,"panels":[],"title":"Storage","type":"row"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisBorderShow":false,"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"ops"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":35},"id":1,"options":{"legend":{"calcs":["lastNotNull"],"displayMode":"table","placement":"bottom","showLegend":true},"tooltip":{"maxHeight":600,"mode":"multi","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"sum(rate(foyer_storage_op_total[$__rate_interval])) by (name, op)","instant":false,"legendFormat":"{{name}} - storage - {{op}}","range":true,"refId":"A"}],"title":"Op","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisBorderShow":false,"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"ops"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":35},"id":2,"options":{"legend":{"calcs":["lastNotNull"],"displayMode":"table","placement":"bottom","showLegend":true},"tooltip":{"maxHeight":600,"mode":"multi","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"sum(rate(foyer_storage_inner_op_total[$__rate_interval])) by (name, op)","instant":false,"legendFormat":"{{name}} - storage - {{op}}","range":true,"refId":"A"}],"title":"Inner Op","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisBorderShow":false,"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"s"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":43},"id":16,"options":{"legend":{"calcs":["lastNotNull"],"displayMode":"table","placement":"bottom","showLegend":true},"tooltip":{"maxHeight":600,"mode":"multi","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(0.5, sum(rate(foyer_storage_op_duration_bucket[$__rate_interval])) by (le, name, op)) ","instant":false,"legendFormat":"p50 - {{name}} - storage - {{op}}","range":true,"refId":"A"},{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(0.9, sum(rate(foyer_storage_op_duration_bucket[$__rate_interval])) by (le, name, op)) ","hide":false,"instant":false,"legendFormat":"p90 - {{name}} - storage - {{op}}","range":true,"refId":"B"},{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(0.99, sum(rate(foyer_storage_op_duration_bucket[$__rate_interval])) by (le, name, op)) ","hide":false,"instant":false,"legendFormat":"p99 - {{name}} - storage - {{op}}","range":true,"refId":"C"},{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(1.0, sum(rate(foyer_storage_op_duration_bucket[$__rate_interval])) by (le, name, op)) ","hide":false,"instant":false,"legendFormat":"pmax - {{name}} - storage - {{op}}","range":true,"refId":"D"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"editorMode":"code","expr":"sum(rate(foyer_storage_op_duration_sum[$__rate_interval])) by (le, name, op) / sum(rate(foyer_storage_op_duration_count[$__rate_interval])) by (le, name, op)","hide":false,"instant":false,"legendFormat":"pavg - {{name}} - storage - {{op}}","range":true,"refId":"E"}],"title":"Op Duration","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisBorderShow":false,"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"s"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":43},"id":17,"options":{"legend":{"calcs":["lastNotNull"],"displayMode":"table","placement":"bottom","showLegend":true},"tooltip":{"maxHeight":600,"mode":"multi","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(0.5, sum(rate(foyer_storage_inner_op_duration_bucket[$__rate_interval])) by (le, name, op)) ","instant":false,"legendFormat":"p50 - {{name}} - storage - {{op}}","range":true,"refId":"A"},{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(0.9, sum(rate(foyer_storage_inner_op_duration_bucket[$__rate_interval])) by (le, name, op)) ","hide":false,"instant":false,"legendFormat":"p90 - {{name}} - storage - {{op}}","range":true,"refId":"B"},{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(0.99, sum(rate(foyer_storage_inner_op_duration_bucket[$__rate_interval])) by (le, name, op)) ","hide":false,"instant":false,"legendFormat":"p99 - {{name}} - storage - {{op}}","range":true,"refId":"C"},{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(1.0, sum(rate(foyer_storage_inner_op_duration_bucket[$__rate_interval])) by (le, name, op)) ","hide":false,"instant":false,"legendFormat":"pmax - {{name}} - storage - {{op}}","range":true,"refId":"D"},{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"sum(rate(foyer_storage_inner_op_duration_sum[$__rate_interval])) by (le, name, op) / sum(rate(foyer_storage_inner_op_duration_count[$__rate_interval])) by (le, name, op)","hide":false,"instant":false,"legendFormat":"pavg - {{name}} - storage - {{op}}","range":true,"refId":"E"}],"title":"Inner Op Duration","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisBorderShow":false,"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]}},"overrides":[{"matcher":{"id":"byFrameRefID","options":"B"},"properties":[{"id":"unit"}]}]},"gridPos":{"h":8,"w":12,"x":0,"y":51},"id":27,"options":{"legend":{"calcs":["lastNotNull"],"displayMode":"table","placement":"bottom","showLegend":true},"tooltip":{"maxHeight":600,"mode":"multi","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"sum(foyer_storage_region) by (name, type)","instant":false,"legendFormat":"{{name}} - region - {{type}}","range":true,"refId":"A"}],"title":"Region Count","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisBorderShow":false,"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"decbytes"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":51},"id":28,"options":{"legend":{"calcs":["lastNotNull"],"displayMode":"table","placement":"bottom","showLegend":true},"tooltip":{"maxHeight":600,"mode":"multi","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"sum(foyer_storage_region) by (name, type) * on(name) group_left() foyer_storage_region_size_bytes","instant":false,"legendFormat":"{{name}} - region - {{type}}","range":true,"refId":"A"}],"title":"Region Size","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisBorderShow":false,"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"percentunit"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":59},"id":18,"options":{"legend":{"calcs":["lastNotNull"],"displayMode":"table","placement":"bottom","showLegend":true},"tooltip":{"maxHeight":600,"mode":"multi","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"sum(rate(foyer_storage_op_total{op=\"hit\"}[$__rate_interval])) by (name) / (sum(rate(foyer_storage_op_total{op=\"hit\"}[$__rate_interval])) by (name) + sum(rate(foyer_storage_op_total{op=\"miss\"}[$__rate_interval])) by (name)) ","instant":false,"legendFormat":"{{name}} - storage - hit ratio","range":true,"refId":"A"}],"title":"Hit Ratio","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisBorderShow":false,"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"s"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":59},"id":29,"options":{"legend":{"calcs":["lastNotNull"],"displayMode":"table","placement":"bottom","showLegend":true},"tooltip":{"maxHeight":600,"mode":"multi","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(0.5, sum(rate(foyer_storage_entry_serde_duration_bucket[$__rate_interval])) by (le, name, op))","instant":false,"legendFormat":"p50 - {{name}} - storage - {{op}}","range":true,"refId":"A"},{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(0.9, sum(rate(foyer_storage_entry_serde_duration_bucket[$__rate_interval])) by (le, name, op))","hide":false,"instant":false,"legendFormat":"p90 - {{name}} - storage - {{op}}","range":true,"refId":"B"},{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(0.99, sum(rate(foyer_storage_entry_serde_duration_bucket[$__rate_interval])) by (le, name, op))","hide":false,"instant":false,"legendFormat":"p99 - {{name}} - storage - {{op}}","range":true,"refId":"C"},{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(1.0, sum(rate(foyer_storage_entry_serde_duration_bucket[$__rate_interval])) by (le, name, op))","hide":false,"instant":false,"legendFormat":"pmax - {{name}} - storage - {{op}}","range":true,"refId":"D"},{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"sum(rate(foyer_storage_entry_serde_duration_sum[$__rate_interval])) by (le, name, op) / sum(rate(foyer_storage_entry_serde_duration_count[$__rate_interval])) by (le, name, op)","hide":false,"instant":false,"legendFormat":"pavg - {{name}} - storage - {{op}}","range":true,"refId":"E"}],"title":"Serde Duration","type":"timeseries"},{"collapsed":false,"gridPos":{"h":1,"w":24,"x":0,"y":67},"id":19,"panels":[],"title":"Storage (Disk)","type":"row"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisBorderShow":false,"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"ops"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":68},"id":20,"options":{"legend":{"calcs":["lastNotNull"],"displayMode":"table","placement":"bottom","showLegend":true},"tooltip":{"maxHeight":600,"mode":"multi","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"sum(rate(foyer_storage_disk_io_total[$__rate_interval])) by (name, op)","instant":false,"legendFormat":"{{name}} - disk io - {{op}}","range":true,"refId":"A"}],"title":"Disk IO","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisBorderShow":false,"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"s"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":12,"y":68},"id":21,"options":{"legend":{"calcs":["lastNotNull"],"displayMode":"table","placement":"bottom","showLegend":true},"tooltip":{"maxHeight":600,"mode":"multi","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(0.5, sum(rate(foyer_storage_disk_io_duration_bucket[$__rate_interval])) by (le, name, op)) ","instant":false,"legendFormat":"p50 - {{name}} - disk io - {{op}}","range":true,"refId":"A"},{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(0.9, sum(rate(foyer_storage_disk_io_duration_bucket[$__rate_interval])) by (le, name, op)) ","hide":false,"instant":false,"legendFormat":"p90 - {{name}} - disk io - {{op}}","range":true,"refId":"B"},{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(0.99, sum(rate(foyer_storage_disk_io_duration_bucket[$__rate_interval])) by (le, name, op)) ","hide":false,"instant":false,"legendFormat":"p99 - {{name}} - disk io - {{op}}","range":true,"refId":"C"},{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"histogram_quantile(1.0, sum(rate(foyer_storage_disk_io_duration_bucket[$__rate_interval])) by (le, name, op)) ","hide":false,"instant":false,"legendFormat":"pmax - {{name}} - disk io - {{op}}","range":true,"refId":"D"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"editorMode":"code","expr":"sum(rate(foyer_storage_disk_io_duration_sum[$__rate_interval])) by (le, name, op) / sum(rate(foyer_storage_disk_io_duration_count[$__rate_interval])) by (le, name, op)","hide":false,"instant":false,"legendFormat":"pavg - {{name}} - disk io - {{op}}","range":true,"refId":"E"}],"title":"Disk IO Duration","type":"timeseries"},{"datasource":{"type":"prometheus","uid":"P92AEBB27A9B79E22"},"fieldConfig":{"defaults":{"color":{"mode":"palette-classic"},"custom":{"axisBorderShow":false,"axisCenteredZero":false,"axisColorMode":"text","axisLabel":"","axisPlacement":"auto","barAlignment":0,"drawStyle":"line","fillOpacity":10,"gradientMode":"none","hideFrom":{"legend":false,"tooltip":false,"viz":false},"insertNulls":false,"lineInterpolation":"linear","lineWidth":1,"pointSize":5,"scaleDistribution":{"type":"linear"},"showPoints":"auto","spanNulls":false,"stacking":{"group":"A","mode":"none"},"thresholdsStyle":{"mode":"off"}},"mappings":[],"min":0,"thresholds":{"mode":"absolute","steps":[{"color":"green","value":null},{"color":"red","value":80}]},"unit":"Bps"},"overrides":[]},"gridPos":{"h":8,"w":12,"x":0,"y":76},"id":5,"options":{"legend":{"calcs":["lastNotNull"],"displayMode":"table","placement":"bottom","showLegend":true},"tooltip":{"maxHeight":600,"mode":"multi","sort":"none"}},"targets":[{"datasource":{"type":"prometheus","uid":"a2641a73-8591-446b-9d69-7869ebf43899"},"editorMode":"code","expr":"sum(rate(foyer_storage_disk_io_bytes[$__rate_interval])) by (foyer, op, extra) ","instant":false,"legendFormat":"{{foyer}} foyer storage - {{op}} {{extra}}","range":true,"refId":"A"}],"title":"Op Thoughput","type":"timeseries"}],"refresh":"5s","schemaVersion":39,"tags":[],"templating":{"list":[]},"time":{"from":"now-30m","to":"now"},"timepicker":{},"timezone":"","title":"foyer","uid":"f0e2058b-b292-457c-8ddf-9dbdf7c60035","version":1,"weekStart":""} diff --git a/foyer-bench/Cargo.toml b/foyer-bench/Cargo.toml index 1b8304b8..9036bd76 100644 --- a/foyer-bench/Cargo.toml +++ b/foyer-bench/Cargo.toml @@ -33,7 +33,7 @@ opentelemetry_sdk = { version = "0.24", features = [ parking_lot = "0.12" rand = "0.8.5" serde = { workspace = true } -serde_bytes = "0.11.14" +serde_bytes = "0.11.15" tokio = { workspace = true } tracing = "0.1" tracing-opentelemetry = { version = "0.25", optional = true } diff --git a/foyer-common/src/metrics.rs b/foyer-common/src/metrics.rs index 47b2f353..f1f81132 100644 --- a/foyer-common/src/metrics.rs +++ b/foyer-common/src/metrics.rs @@ -66,6 +66,9 @@ pub struct Metrics { pub storage_region_size_bytes: Gauge, + pub storage_entry_serialize_duration: Histogram, + pub storage_entry_deserialize_duration: Histogram, + /* hybrid cache metrics */ pub hybrid_insert: Counter, pub hybrid_hit: Counter, @@ -156,6 +159,10 @@ impl Metrics { let storage_region_size_bytes = gauge!(format!("foyer_storage_region_size_bytes"), "name" => name.to_string()); + let storage_entry_serialize_duration = + histogram!(format!("foyer_storage_entry_serde_duration"), "name" => name.to_string(), "op" => "serialize"); + let storage_entry_deserialize_duration = histogram!(format!("foyer_storage_entry_serde_duration"), "name" => name.to_string(), "op" => "deserialize"); + /* hybrid cache metrics */ let hybrid_insert = counter!(format!("foyer_hybrid_op_total"), "name" => name.to_string(), "op" => "insert"); @@ -210,6 +217,8 @@ impl Metrics { storage_region_clean, storage_region_evictable, storage_region_size_bytes, + storage_entry_serialize_duration, + storage_entry_deserialize_duration, hybrid_insert, hybrid_hit, diff --git a/foyer-storage/src/large/generic.rs b/foyer-storage/src/large/generic.rs index 23de2d63..3c94491e 100644 --- a/foyer-storage/src/large/generic.rs +++ b/foyer-storage/src/large/generic.rs @@ -228,6 +228,7 @@ where &indexer, ®ion_manager, &tombstones, + metrics.clone(), config.user_runtime_handle.clone(), ) .await?; @@ -256,6 +257,7 @@ where flushers.clone(), stats.clone(), config.flush, + metrics.clone(), config.write_runtime_handle.clone(), ) .await @@ -346,6 +348,7 @@ where header.value_len as _, header.compression, Some(header.checksum), + &metrics, ) { Ok(res) => res, Err(e) => match e { @@ -499,7 +502,7 @@ mod tests { }, picker::utils::{FifoPicker, RejectAllPicker}, serde::EntrySerializer, - test_utils::BiasedPicker, + test_utils::{metrics_for_test, BiasedPicker}, IoBytesMut, TombstoneLogConfigBuilder, }; @@ -594,7 +597,14 @@ mod tests { fn enqueue(store: &GenericLargeStorage, RandomState>, entry: CacheEntry, RandomState>) { let mut buffer = IoBytesMut::new(); - let info = EntrySerializer::serialize(entry.key(), entry.value(), &Compression::None, &mut buffer).unwrap(); + let info = EntrySerializer::serialize( + entry.key(), + entry.value(), + &Compression::None, + &mut buffer, + metrics_for_test(), + ) + .unwrap(); let buffer = buffer.freeze(); store.enqueue(entry, buffer, info); } diff --git a/foyer-storage/src/large/reclaimer.rs b/foyer-storage/src/large/reclaimer.rs index 29238828..92e7fddb 100644 --- a/foyer-storage/src/large/reclaimer.rs +++ b/foyer-storage/src/large/reclaimer.rs @@ -14,7 +14,10 @@ use std::{fmt::Debug, future::Future, sync::Arc, time::Duration}; -use foyer_common::code::{HashBuilder, StorageKey, StorageValue}; +use foyer_common::{ + code::{HashBuilder, StorageKey, StorageValue}, + metrics::Metrics, +}; use futures::future::join_all; use itertools::Itertools; use tokio::{ @@ -53,6 +56,7 @@ impl Reclaimer { flushers: Vec>, stats: Arc, flush: bool, + metrics: Arc, runtime: Handle, ) -> Self where @@ -70,6 +74,7 @@ impl Reclaimer { reinsertion_picker, stats, flush, + metrics, wait_rx, runtime: runtime.clone(), }; @@ -108,6 +113,8 @@ where flush: bool, + metrics: Arc, + wait_rx: mpsc::UnboundedReceiver>, runtime: Handle, @@ -167,7 +174,7 @@ where tracing::debug!("[reclaimer]: Start reclaiming region {id}."); - let mut scanner = RegionScanner::new(region.clone()); + let mut scanner = RegionScanner::new(region.clone(), self.metrics.clone()); let mut picked_count = 0; let mut unpicked = vec![]; // The loop will ends when: diff --git a/foyer-storage/src/large/recover.rs b/foyer-storage/src/large/recover.rs index 6faa6d25..45470b3e 100644 --- a/foyer-storage/src/large/recover.rs +++ b/foyer-storage/src/large/recover.rs @@ -21,6 +21,7 @@ use std::sync::Arc; use clap::ValueEnum; use foyer_common::code::{HashBuilder, StorageKey, StorageValue}; +use foyer_common::metrics::Metrics; use futures::future::try_join_all; use itertools::Itertools; @@ -61,6 +62,8 @@ pub enum RecoverMode { pub struct RecoverRunner; impl RecoverRunner { + // TODO(MrCroxx): use `expect` after `lint_reasons` is stable. + #[allow(clippy::too_many_arguments)] pub async fn run( config: &GenericLargeStorageConfig, regions: Range, @@ -68,6 +71,7 @@ impl RecoverRunner { indexer: &Indexer, region_manager: &RegionManager, tombstones: &[Tombstone], + metrics: Arc, runtime: Handle, ) -> Result<()> where @@ -81,9 +85,10 @@ impl RecoverRunner { let handles = regions.map(|id| { let semaphore = semaphore.clone(); let region = region_manager.region(id).clone(); + let metrics = metrics.clone(); runtime.spawn(async move { let permit = semaphore.acquire().await; - let res = RegionRecoverRunner::run(mode, region).await; + let res = RegionRecoverRunner::run(mode, region, metrics).await; drop(permit); res }) @@ -194,7 +199,7 @@ impl RecoverRunner { struct RegionRecoverRunner; impl RegionRecoverRunner { - async fn run(mode: RecoverMode, region: Region) -> Result> { + async fn run(mode: RecoverMode, region: Region, metrics: Arc) -> Result> { if mode == RecoverMode::None { return Ok(vec![]); } @@ -202,7 +207,7 @@ impl RegionRecoverRunner { let mut infos = vec![]; let id = region.id(); - let mut iter = RegionScanner::new(region); + let mut iter = RegionScanner::new(region, metrics); loop { let r = iter.next().await; match r { diff --git a/foyer-storage/src/large/scanner.rs b/foyer-storage/src/large/scanner.rs index cd6c4fe0..bd09a452 100644 --- a/foyer-storage/src/large/scanner.rs +++ b/foyer-storage/src/large/scanner.rs @@ -12,9 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::sync::Arc; + use foyer_common::{ bits, code::{StorageKey, StorageValue}, + metrics::Metrics, strict_assert, }; @@ -83,15 +86,17 @@ pub struct RegionScanner { region: Region, offset: u64, cache: CachedDeviceReader, + metrics: Arc, } impl RegionScanner { - pub fn new(region: Region) -> Self { + pub fn new(region: Region, metrics: Arc) -> Self { let cache = CachedDeviceReader::new(region.clone()); Self { region, offset: 0, cache, + metrics, } } @@ -216,6 +221,7 @@ impl RegionScanner { header.value_len as _, header.compression, Some(header.checksum), + &self.metrics, )?; self.step(&header).await; diff --git a/foyer-storage/src/serde.rs b/foyer-storage/src/serde.rs index fe63184e..de9bcb50 100644 --- a/foyer-storage/src/serde.rs +++ b/foyer-storage/src/serde.rs @@ -12,10 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::{fmt::Debug, hash::Hasher}; +use std::{fmt::Debug, hash::Hasher, time::Instant}; use twox_hash::XxHash64; -use foyer_common::code::{StorageKey, StorageValue}; +use foyer_common::{ + code::{StorageKey, StorageValue}, + metrics::Metrics, +}; use crate::{ compress::Compression, @@ -51,11 +54,14 @@ impl EntrySerializer { value: &'a V, compression: &'a Compression, mut buffer: &'a mut IoBytesMut, + metrics: &Metrics, ) -> Result where K: StorageKey, V: StorageValue, { + let now = Instant::now(); + let mut cursor = buffer.len(); // serialize value @@ -85,6 +91,8 @@ impl EntrySerializer { bincode::serialize_into(&mut buffer, &key).map_err(Error::from)?; let key_len = buffer.len() - cursor; + metrics.storage_entry_serialize_duration.record(now.elapsed()); + Ok(KvInfo { key_len, value_len }) } } @@ -100,11 +108,14 @@ impl EntryDeserializer { value_len: usize, compression: Compression, checksum: Option, + metrics: &Metrics, ) -> Result<(K, V)> where K: StorageKey, V: StorageValue, { + let now = Instant::now(); + // deserialize value let buf = &buffer[..value_len]; let value = Self::deserialize_value(buf, compression)?; @@ -121,6 +132,8 @@ impl EntryDeserializer { } } + metrics.storage_entry_deserialize_duration.record(now.elapsed()); + Ok((key, value)) } diff --git a/foyer-storage/src/store.rs b/foyer-storage/src/store.rs index dcccd1ae..82cfcb99 100644 --- a/foyer-storage/src/store.rs +++ b/foyer-storage/src/store.rs @@ -143,7 +143,13 @@ where self.inner.write_runtime_handle.spawn(async move { if force || this.pick(entry.key()) { let mut buffer = IoBytesMut::new(); - match EntrySerializer::serialize(entry.key(), entry.value(), &compression, &mut buffer) { + match EntrySerializer::serialize( + entry.key(), + entry.value(), + &compression, + &mut buffer, + &this.inner.metrics, + ) { Ok(info) => { let buffer = buffer.freeze(); this.inner.engine.enqueue(entry, buffer, info); diff --git a/foyer-storage/src/test_utils.rs b/foyer-storage/src/test_utils.rs index 8275f710..26132575 100644 --- a/foyer-storage/src/test_utils.rs +++ b/foyer-storage/src/test_utils.rs @@ -14,9 +14,16 @@ //! Test utils for the `foyer-storage` crate. -use std::{borrow::Borrow, collections::HashSet, fmt::Debug, hash::Hash, marker::PhantomData, sync::Arc}; +use std::{ + borrow::Borrow, + collections::HashSet, + fmt::Debug, + hash::Hash, + marker::PhantomData, + sync::{Arc, OnceLock}, +}; -use foyer_common::code::StorageKey; +use foyer_common::{code::StorageKey, metrics::Metrics}; use parking_lot::Mutex; use crate::{ @@ -24,6 +31,14 @@ use crate::{ statistics::Statistics, }; +/// A phantom metrics for test. +static METRICS_FOR_TEST: OnceLock = OnceLock::new(); + +/// Get a phantom metrics for test. +pub fn metrics_for_test() -> &'static Metrics { + METRICS_FOR_TEST.get_or_init(|| Metrics::new("test")) +} + /// A picker that only admits key from the given list. pub struct BiasedPicker { admits: HashSet, From 14f0d32609cc03b58424bf95d03f0a1bbfe9f750 Mon Sep 17 00:00:00 2001 From: Croxx Date: Thu, 22 Aug 2024 02:05:00 +0800 Subject: [PATCH 05/40] chore: fmt code with unstable fmt features (#667) * chore: fmt code with unstable fmt features Signed-off-by: MrCroxx * chore: add ffmt task to make file Signed-off-by: MrCroxx * chore: add rust ffmt check to CI Signed-off-by: MrCroxx * chore: fix ci Signed-off-by: MrCroxx --------- Signed-off-by: MrCroxx --- .github/template/template.yml | 37 ++++++++++++++++++- .github/workflows/main.yml | 38 ++++++++++++++++++- .github/workflows/pull-request.yml | 38 ++++++++++++++++++- Makefile | 5 ++- foyer-bench/src/main.rs | 19 +++++----- foyer-common/src/fs.rs | 3 +- foyer-common/src/future.rs | 3 +- foyer-common/src/tracing.rs | 5 +-- foyer-common/src/wait_group.rs | 6 +-- foyer-memory/src/cache.rs | 9 ++--- foyer-memory/src/eviction/sanity.rs | 3 +- foyer-memory/src/generic.rs | 3 +- foyer-memory/src/handle.rs | 1 - foyer-memory/src/indexer/hash_table.rs | 6 +-- foyer-memory/src/indexer/sanity.rs | 3 +- foyer-memory/src/prelude.rs | 3 +- foyer-storage/src/device/bytes.rs | 3 +- foyer-storage/src/device/direct_file.rs | 13 +++---- foyer-storage/src/device/direct_fs.rs | 2 - foyer-storage/src/device/mod.rs | 9 +++-- foyer-storage/src/device/monitor.rs | 3 +- foyer-storage/src/engine.rs | 9 +++-- foyer-storage/src/large/batch.rs | 26 ++++++------- foyer-storage/src/large/flusher.rs | 25 +++++++------ foyer-storage/src/large/generic.rs | 27 ++++++-------- foyer-storage/src/large/recover.rs | 49 +++++++++++++------------ foyer-storage/src/large/scanner.rs | 3 +- foyer-storage/src/large/serde.rs | 3 +- foyer-storage/src/large/tombstone.rs | 6 +-- foyer-storage/src/picker/mod.rs | 3 +- foyer-storage/src/picker/utils.rs | 3 +- foyer-storage/src/serde.rs | 2 +- foyer-storage/src/small/generic.rs | 4 +- foyer-storage/src/storage/either.rs | 14 +++---- foyer-storage/src/storage/noop.rs | 11 +----- foyer-storage/src/store.rs | 22 ++++++----- foyer/src/hybrid/cache.rs | 3 +- foyer/src/hybrid/writer.rs | 10 +++-- foyer/src/prelude.rs | 6 +-- rustfmt.nightly.toml | 8 ++++ rustfmt.toml | 6 --- 41 files changed, 273 insertions(+), 179 deletions(-) create mode 100644 rustfmt.nightly.toml diff --git a/.github/template/template.yml b/.github/template/template.yml index bd69a0e6..8d638b2c 100644 --- a/.github/template/template.yml +++ b/.github/template/template.yml @@ -65,7 +65,42 @@ jobs: env: RUSTFLAGS: "--cfg tokio_unstable -Awarnings" run: | - cargo udeps --all-targets + cargo udeps --all-targets + rust-ffmt-check: + name: rust ffmt check + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest] + runs-on: ${{ matrix.os }} + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install rust toolchain + uses: dtolnay/rust-toolchain@master + with: + toolchain: nightly + components: rustfmt + - name: Cache Cargo home + uses: actions/cache@v4 + id: cache + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }}-${{ env.CACHE_KEY_SUFFIX }}-rust-ffmt-check + - name: Fastidious Format Check + run: | + cargo fmt --all --check -- --config-path rustfmt.nightly.toml + - name: Hint + if: ${{ failure() }} + run: |- + echo "The ffmt (Fastidious Format Check) test is not a necessary." + echo "It uses unstable features to achieve a better format." + echo "If you want to pass the test, please install the nightly toolchain with \`rustup install nightly\`." + echo "Then run \`make ffmt\`." rust-test: name: rust test with codecov strategy: diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a4d967eb..0e57ce28 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -71,7 +71,43 @@ jobs: - name: Unused Dependencies Check env: RUSTFLAGS: "--cfg tokio_unstable -Awarnings" - run: "cargo udeps --all-targets \n" + run: | + cargo udeps --all-targets + rust-ffmt-check: + name: rust ffmt check + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest] + runs-on: ${{ matrix.os }} + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install rust toolchain + uses: dtolnay/rust-toolchain@master + with: + toolchain: nightly + components: rustfmt + - name: Cache Cargo home + uses: actions/cache@v4 + id: cache + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }}-${{ env.CACHE_KEY_SUFFIX }}-rust-ffmt-check + - name: Fastidious Format Check + run: | + cargo fmt --all --check -- --config-path rustfmt.nightly.toml + - name: Hint + if: ${{ failure() }} + run: |- + echo "The ffmt (Fastidious Format Check) test is not a necessary." + echo "It uses unstable features to achieve a better format." + echo "If you want to pass the test, please install the nightly toolchain with \`rustup install nightly\`." + echo "Then run \`make ffmt\`." rust-test: name: rust test with codecov strategy: diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index abc9a0d7..fe48b0b3 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -70,7 +70,43 @@ jobs: - name: Unused Dependencies Check env: RUSTFLAGS: "--cfg tokio_unstable -Awarnings" - run: "cargo udeps --all-targets \n" + run: | + cargo udeps --all-targets + rust-ffmt-check: + name: rust ffmt check + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest] + runs-on: ${{ matrix.os }} + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install rust toolchain + uses: dtolnay/rust-toolchain@master + with: + toolchain: nightly + components: rustfmt + - name: Cache Cargo home + uses: actions/cache@v4 + id: cache + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }}-${{ env.CACHE_KEY_SUFFIX }}-rust-ffmt-check + - name: Fastidious Format Check + run: | + cargo fmt --all --check -- --config-path rustfmt.nightly.toml + - name: Hint + if: ${{ failure() }} + run: |- + echo "The ffmt (Fastidious Format Check) test is not a necessary." + echo "It uses unstable features to achieve a better format." + echo "If you want to pass the test, please install the nightly toolchain with \`rustup install nightly\`." + echo "Then run \`make ffmt\`." rust-test: name: rust test with codecov strategy: diff --git a/Makefile b/Makefile index 5620b204..a5545ef6 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ SHELL := /bin/bash -.PHONY: deps check test test-ignored test-all all fast monitor clear madsim example msrv udeps +.PHONY: deps check test test-ignored test-all all fast monitor clear madsim example msrv udeps ffmt deps: ./scripts/install-deps.sh @@ -74,3 +74,6 @@ monitor: clear: rm -rf .tmp + +ffmt: + cargo +nightly fmt --all -- --config-path rustfmt.nightly.toml \ No newline at end of file diff --git a/foyer-bench/src/main.rs b/foyer-bench/src/main.rs index 80a7e75c..f24b8547 100644 --- a/foyer-bench/src/main.rs +++ b/foyer-bench/src/main.rs @@ -16,14 +16,6 @@ mod analyze; mod rate; mod text; -use bytesize::MIB; -use foyer::{ - Compression, DirectFileDeviceOptionsBuilder, DirectFsDeviceOptionsBuilder, FifoConfig, FifoPicker, HybridCache, - HybridCacheBuilder, InvalidRatioPicker, LfuConfig, LruConfig, RateLimitPicker, RecoverMode, RuntimeConfig, - S3FifoConfig, TokioRuntimeConfig, TracingConfig, -}; -use metrics_exporter_prometheus::PrometheusBuilder; - use std::{ collections::BTreeMap, fs::create_dir_all, @@ -37,10 +29,16 @@ use std::{ }; use analyze::{analyze, monitor, Metrics}; +use bytesize::MIB; use clap::{builder::PossibleValuesParser, ArgGroup, Parser}; - +use foyer::{ + Compression, DirectFileDeviceOptionsBuilder, DirectFsDeviceOptionsBuilder, FifoConfig, FifoPicker, HybridCache, + HybridCacheBuilder, InvalidRatioPicker, LfuConfig, LruConfig, RateLimitPicker, RecoverMode, RuntimeConfig, + S3FifoConfig, TokioRuntimeConfig, TracingConfig, +}; use futures::future::join_all; use itertools::Itertools; +use metrics_exporter_prometheus::PrometheusBuilder; use rand::{ distributions::Distribution, rngs::{OsRng, StdRng}, @@ -313,9 +311,10 @@ impl Deref for Value { } mod arc_bytes { + use std::sync::Arc; + use serde::{Deserialize, Deserializer, Serializer}; use serde_bytes::ByteBuf; - use std::sync::Arc; pub fn serialize(data: &Arc>, serializer: S) -> Result where diff --git a/foyer-common/src/fs.rs b/foyer-common/src/fs.rs index 027786ad..fdc42dbf 100644 --- a/foyer-common/src/fs.rs +++ b/foyer-common/src/fs.rs @@ -30,9 +30,10 @@ mod tests { process::Command, }; - use super::*; use itertools::Itertools; + use super::*; + #[test] #[ignore] fn test() { diff --git a/foyer-common/src/future.rs b/foyer-common/src/future.rs index d609e2a1..5e9ec127 100644 --- a/foyer-common/src/future.rs +++ b/foyer-common/src/future.rs @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -use pin_project::pin_project; use std::{ future::Future, marker::PhantomData, @@ -21,6 +20,8 @@ use std::{ task::{ready, Context, Poll}, }; +use pin_project::pin_project; + /// Result that the inner future of a [`DiversionFuture`] should return. /// /// - The `target` will be further returned by [`DiversionFuture`]. diff --git a/foyer-common/src/tracing.rs b/foyer-common/src/tracing.rs index 1c1ffbc9..708b5208 100644 --- a/foyer-common/src/tracing.rs +++ b/foyer-common/src/tracing.rs @@ -12,9 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -use fastrace::prelude::*; -use serde::{Deserialize, Serialize}; - use std::{ ops::Deref, pin::Pin, @@ -23,8 +20,10 @@ use std::{ time::Duration, }; +use fastrace::prelude::*; use futures::{ready, Future}; use pin_project::pin_project; +use serde::{Deserialize, Serialize}; /// Configurations for tracing. #[derive(Debug, Serialize, Deserialize)] diff --git a/foyer-common/src/wait_group.rs b/foyer-common/src/wait_group.rs index e3066e90..c6bd1f28 100644 --- a/foyer-common/src/wait_group.rs +++ b/foyer-common/src/wait_group.rs @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -use futures::{task::AtomicWaker, Future}; use std::{ pin::Pin, sync::{ @@ -22,6 +21,8 @@ use std::{ task::{Context, Poll}, }; +use futures::{task::AtomicWaker, Future}; + #[derive(Debug, Default)] struct WaitGroupInner { counter: AtomicUsize, @@ -64,8 +65,7 @@ impl Drop for WaitGroupGuard { // Wake up the future if this is the last count. // // - If the waker is not set yet, this is a no-op. The counter might be increased again later. - // - If the waker is already set, the counter will be no longer increased, - // so this is the actual last count. + // - If the waker is already set, the counter will be no longer increased, so this is the actual last count. self.inner.waker.wake(); } } diff --git a/foyer-memory/src/cache.rs b/foyer-memory/src/cache.rs index b7f82375..8e50ca02 100644 --- a/foyer-memory/src/cache.rs +++ b/foyer-memory/src/cache.rs @@ -15,16 +15,15 @@ use std::{borrow::Borrow, fmt::Debug, hash::Hash, ops::Deref, sync::Arc}; use ahash::RandomState; -use futures::Future; -use pin_project::pin_project; -use serde::{Deserialize, Serialize}; -use tokio::sync::oneshot; - use foyer_common::{ code::{HashBuilder, Key, Value}, event::EventListener, future::Diversion, }; +use futures::Future; +use pin_project::pin_project; +use serde::{Deserialize, Serialize}; +use tokio::sync::oneshot; use crate::{ context::CacheContext, diff --git a/foyer-memory/src/eviction/sanity.rs b/foyer-memory/src/eviction/sanity.rs index 02b83a69..176ede26 100644 --- a/foyer-memory/src/eviction/sanity.rs +++ b/foyer-memory/src/eviction/sanity.rs @@ -12,11 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. +use super::Eviction; #[cfg(feature = "sanity")] use crate::handle::Handle; -use super::Eviction; - pub struct SanityEviction where E: Eviction, diff --git a/foyer-memory/src/generic.rs b/foyer-memory/src/generic.rs index 5f1eaddf..9d42dc46 100644 --- a/foyer-memory/src/generic.rs +++ b/foyer-memory/src/generic.rs @@ -28,6 +28,7 @@ use std::{ }; use ahash::RandomState; +use fastrace::{future::InSpan, prelude::*}; use foyer_common::{ code::{HashBuilder, Key, Value}, event::EventListener, @@ -49,8 +50,6 @@ use crate::{ CacheContext, }; -use fastrace::{future::InSpan, prelude::*}; - // TODO(MrCroxx): Use `trait_alias` after stable. /// The weighter for the in-memory cache. /// diff --git a/foyer-memory/src/handle.rs b/foyer-memory/src/handle.rs index bf7a8025..5f4254ae 100644 --- a/foyer-memory/src/handle.rs +++ b/foyer-memory/src/handle.rs @@ -13,7 +13,6 @@ // limitations under the License. use bitflags::bitflags; - use foyer_common::{ assert::OptionExt, code::{Key, Value}, diff --git a/foyer-memory/src/indexer/hash_table.rs b/foyer-memory/src/indexer/hash_table.rs index c8a63b7f..b0837d72 100644 --- a/foyer-memory/src/indexer/hash_table.rs +++ b/foyer-memory/src/indexer/hash_table.rs @@ -14,13 +14,11 @@ use std::{borrow::Borrow, hash::Hash, ptr::NonNull}; -use hashbrown::hash_table::{Entry as HashTableEntry, HashTable}; - use foyer_common::{code::Key, strict_assert}; - -use crate::handle::KeyedHandle; +use hashbrown::hash_table::{Entry as HashTableEntry, HashTable}; use super::Indexer; +use crate::handle::KeyedHandle; pub struct HashTableIndexer where diff --git a/foyer-memory/src/indexer/sanity.rs b/foyer-memory/src/indexer/sanity.rs index 743ba206..d84b59ed 100644 --- a/foyer-memory/src/indexer/sanity.rs +++ b/foyer-memory/src/indexer/sanity.rs @@ -14,11 +14,10 @@ use std::ptr::NonNull; +use super::Indexer; #[cfg(feature = "sanity")] use crate::handle::Handle; -use super::Indexer; - pub struct SanityIndexer where I: Indexer, diff --git a/foyer-memory/src/prelude.rs b/foyer-memory/src/prelude.rs index a7628524..d1cd10ed 100644 --- a/foyer-memory/src/prelude.rs +++ b/foyer-memory/src/prelude.rs @@ -12,10 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. +pub use ahash::RandomState; + pub use crate::{ cache::{Cache, CacheBuilder, CacheEntry, EvictionConfig, Fetch}, context::CacheContext, eviction::{fifo::FifoConfig, lfu::LfuConfig, lru::LruConfig, s3fifo::S3FifoConfig}, generic::{FetchMark, FetchState, Weighter}, }; -pub use ahash::RandomState; diff --git a/foyer-storage/src/device/bytes.rs b/foyer-storage/src/device/bytes.rs index 13e54b0b..14dbfe91 100644 --- a/foyer-storage/src/device/bytes.rs +++ b/foyer-storage/src/device/bytes.rs @@ -18,11 +18,12 @@ use std::{ sync::Arc, }; -use super::{allocator::AlignedAllocator, ALIGN, IO_BUFFER_ALLOCATOR}; use allocator_api2::{boxed::Box as BoxA, vec::Vec as VecA}; use bytes::{buf::UninitSlice, Buf, BufMut}; use foyer_common::bits; +use super::{allocator::AlignedAllocator, ALIGN, IO_BUFFER_ALLOCATOR}; + /// A capacity-fixed 4K-aligned u8 buffer. pub struct IoBuffer { inner: BoxA<[u8], &'static AlignedAllocator>, diff --git a/foyer-storage/src/device/direct_file.rs b/foyer-storage/src/device/direct_file.rs index d67ea422..7d2f8aa8 100644 --- a/foyer-storage/src/device/direct_file.rs +++ b/foyer-storage/src/device/direct_file.rs @@ -12,6 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::{ + fs::{create_dir_all, File, OpenOptions}, + path::{Path, PathBuf}, + sync::Arc, +}; + use foyer_common::{asyncify::asyncify_with_runtime, bits, fs::freespace}; use serde::{Deserialize, Serialize}; use tokio::runtime::Handle; @@ -22,11 +28,6 @@ use crate::{ error::{Error, Result}, IoBytes, IoBytesMut, }; -use std::{ - fs::{create_dir_all, File, OpenOptions}, - path::{Path, PathBuf}, - sync::Arc, -}; /// Options for the direct file device. #[derive(Debug, Clone, Serialize, Deserialize)] @@ -90,7 +91,6 @@ impl DirectFileDevice { asyncify_with_runtime(&self.runtime, move || { #[cfg(target_family = "unix")] use std::os::unix::fs::FileExt; - #[cfg(target_family = "windows")] use std::os::windows::fs::FileExt; @@ -127,7 +127,6 @@ impl DirectFileDevice { let mut buffer = asyncify_with_runtime(&self.runtime, move || { #[cfg(target_family = "unix")] use std::os::unix::fs::FileExt; - #[cfg(target_family = "windows")] use std::os::windows::fs::FileExt; diff --git a/foyer-storage/src/device/direct_fs.rs b/foyer-storage/src/device/direct_fs.rs index c8f50329..ed44947a 100644 --- a/foyer-storage/src/device/direct_fs.rs +++ b/foyer-storage/src/device/direct_fs.rs @@ -166,7 +166,6 @@ impl Dev for DirectFsDevice { asyncify_with_runtime(&self.inner.runtime, move || { #[cfg(target_family = "unix")] use std::os::unix::fs::FileExt; - #[cfg(target_family = "windows")] use std::os::windows::fs::FileExt; @@ -202,7 +201,6 @@ impl Dev for DirectFsDevice { let mut buffer = asyncify_with_runtime(&self.inner.runtime, move || { #[cfg(target_family = "unix")] use std::os::unix::fs::FileExt; - #[cfg(target_family = "windows")] use std::os::windows::fs::FileExt; diff --git a/foyer-storage/src/device/mod.rs b/foyer-storage/src/device/mod.rs index bf14def4..23faa656 100644 --- a/foyer-storage/src/device/mod.rs +++ b/foyer-storage/src/device/mod.rs @@ -18,15 +18,16 @@ pub mod direct_file; pub mod direct_fs; pub mod monitor; -use crate::{ - error::Result, DirectFileDevice, DirectFileDeviceOptions, DirectFsDevice, DirectFsDeviceOptions, IoBytes, - IoBytesMut, -}; use std::{fmt::Debug, future::Future}; use allocator::AlignedAllocator; use monitor::Monitored; +use crate::{ + error::Result, DirectFileDevice, DirectFileDeviceOptions, DirectFsDevice, DirectFsDeviceOptions, IoBytes, + IoBytesMut, +}; + pub const ALIGN: usize = 4096; pub const IO_BUFFER_ALLOCATOR: AlignedAllocator = AlignedAllocator::new(); diff --git a/foyer-storage/src/device/monitor.rs b/foyer-storage/src/device/monitor.rs index 88bb913e..35354ace 100644 --- a/foyer-storage/src/device/monitor.rs +++ b/foyer-storage/src/device/monitor.rs @@ -23,9 +23,8 @@ use std::{ use foyer_common::{bits, metrics::Metrics}; -use crate::{error::Result, Dev, DevExt, DevOptions, DirectFileDevice, IoBytes, IoBytesMut}; - use super::RegionId; +use crate::{error::Result, Dev, DevExt, DevOptions, DirectFileDevice, IoBytes, IoBytesMut}; /// The statistics information of the device. #[derive(Debug, Default)] diff --git a/foyer-storage/src/engine.rs b/foyer-storage/src/engine.rs index 0f5a1481..d8d66b86 100644 --- a/foyer-storage/src/engine.rs +++ b/foyer-storage/src/engine.rs @@ -12,10 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -use ahash::RandomState; -use foyer_common::code::{HashBuilder, StorageKey, StorageValue}; -use foyer_memory::CacheEntry; -use futures::Future; use std::{ fmt::Debug, marker::PhantomData, @@ -24,6 +20,11 @@ use std::{ task::{Context, Poll}, }; +use ahash::RandomState; +use foyer_common::code::{HashBuilder, StorageKey, StorageValue}; +use foyer_memory::CacheEntry; +use futures::Future; + use crate::{ error::Result, large::generic::{GenericLargeStorage, GenericLargeStorageConfig}, diff --git a/foyer-storage/src/large/batch.rs b/foyer-storage/src/large/batch.rs index 98c8304f..459f6d9e 100644 --- a/foyer-storage/src/large/batch.rs +++ b/foyer-storage/src/large/batch.rs @@ -12,6 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::{ + fmt::Debug, + mem::ManuallyDrop, + ops::{Deref, DerefMut, Range}, + time::Instant, +}; + use foyer_common::{ bits, code::{HashBuilder, StorageKey, StorageValue}, @@ -21,14 +28,14 @@ use foyer_common::{ }; use foyer_memory::CacheEntry; use itertools::Itertools; -use std::{ - fmt::Debug, - mem::ManuallyDrop, - ops::{Deref, DerefMut, Range}, - time::Instant, -}; use tokio::sync::oneshot; +use super::{ + indexer::{EntryAddress, Indexer}, + reclaimer::Reinsertion, + serde::Sequence, + tombstone::Tombstone, +}; use crate::{ device::{bytes::IoBytes, MonitoredDevice, RegionId}, io_buffer_pool::IoBufferPool, @@ -37,13 +44,6 @@ use crate::{ Dev, DevExt, IoBuffer, }; -use super::{ - indexer::{EntryAddress, Indexer}, - reclaimer::Reinsertion, - serde::Sequence, - tombstone::Tombstone, -}; - pub struct Allocation { _guard: WaitGroupGuard, slice: ManuallyDrop>, diff --git a/foyer-storage/src/large/flusher.rs b/foyer-storage/src/large/flusher.rs index 9c101555..2cef53c7 100644 --- a/foyer-storage/src/large/flusher.rs +++ b/foyer-storage/src/large/flusher.rs @@ -12,14 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{ - device::MonitoredDevice, - error::{Error, Result}, - large::serde::EntryHeader, - region::RegionManager, - serde::{Checksummer, KvInfo}, - Compression, IoBytes, Statistics, +use std::{ + fmt::Debug, + future::Future, + sync::{atomic::Ordering, Arc}, }; + use foyer_common::{ code::{HashBuilder, StorageKey, StorageValue}, metrics::Metrics, @@ -28,11 +26,6 @@ use foyer_common::{ use foyer_memory::CacheEntry; use futures::future::{try_join, try_join_all}; use parking_lot::Mutex; -use std::{ - fmt::Debug, - future::Future, - sync::{atomic::Ordering, Arc}, -}; use tokio::{runtime::Handle, sync::Notify}; use super::{ @@ -43,6 +36,14 @@ use super::{ serde::Sequence, tombstone::{Tombstone, TombstoneLog}, }; +use crate::{ + device::MonitoredDevice, + error::{Error, Result}, + large::serde::EntryHeader, + region::RegionManager, + serde::{Checksummer, KvInfo}, + Compression, IoBytes, Statistics, +}; #[derive(Debug)] pub enum Submission diff --git a/foyer-storage/src/large/generic.rs b/foyer-storage/src/large/generic.rs index 3c94491e..597adcd0 100644 --- a/foyer-storage/src/large/generic.rs +++ b/foyer-storage/src/large/generic.rs @@ -24,6 +24,7 @@ use std::{ time::Instant, }; +use fastrace::prelude::*; use foyer_common::{ bits, code::{HashBuilder, StorageKey, StorageValue}, @@ -31,7 +32,15 @@ use foyer_common::{ }; use foyer_memory::CacheEntry; use futures::future::{join_all, try_join_all}; +use tokio::{runtime::Handle, sync::Semaphore}; +use super::{ + batch::InvalidStats, + flusher::{Flusher, Submission}, + indexer::Indexer, + reclaimer::Reclaimer, + recover::{RecoverMode, RecoverRunner}, +}; use crate::{ compress::Compression, device::{monitor::DeviceStats, Dev, DevExt, MonitoredDevice, RegionId}, @@ -49,18 +58,6 @@ use crate::{ IoBytes, }; -use tokio::{runtime::Handle, sync::Semaphore}; - -use super::{ - batch::InvalidStats, - flusher::{Flusher, Submission}, - indexer::Indexer, - reclaimer::Reclaimer, - recover::{RecoverMode, RecoverRunner}, -}; - -use fastrace::prelude::*; - pub struct GenericLargeStorageConfig where K: StorageKey, @@ -487,14 +484,13 @@ where #[cfg(test)] mod tests { - use super::*; - use std::path::Path; use ahash::RandomState; use foyer_memory::{Cache, CacheBuilder, FifoConfig}; use itertools::Itertools; + use super::*; use crate::{ device::{ direct_fs::DirectFsDeviceOptions, @@ -805,7 +801,8 @@ mod tests { // let dir = tempfile::tempdir().unwrap(); // let memory = cache_for_test(); - // let store = store_for_test_with_admission_picker(&memory, dir.path(), Arc::new(BiasedPicker::new([1]))).await; + // let store = store_for_test_with_admission_picker(&memory, dir.path(), + // Arc::new(BiasedPicker::new([1]))).await; // let e1 = memory.insert(1, vec![1; 7 * KB]); // let e2 = memory.insert(2, vec![2; 7 * KB]); diff --git a/foyer-storage/src/large/recover.rs b/foyer-storage/src/large/recover.rs index 45470b3e..d5f0ac1b 100644 --- a/foyer-storage/src/large/recover.rs +++ b/foyer-storage/src/large/recover.rs @@ -12,37 +12,38 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::collections::HashMap; - -use std::fmt::Debug; -use std::ops::Range; -use std::sync::atomic::Ordering; -use std::sync::Arc; +use std::{ + collections::HashMap, + fmt::Debug, + ops::Range, + sync::{atomic::Ordering, Arc}, +}; use clap::ValueEnum; -use foyer_common::code::{HashBuilder, StorageKey, StorageValue}; -use foyer_common::metrics::Metrics; +use foyer_common::{ + code::{HashBuilder, StorageKey, StorageValue}, + metrics::Metrics, +}; use futures::future::try_join_all; - use itertools::Itertools; use serde::{Deserialize, Serialize}; -use tokio::runtime::Handle; -use tokio::sync::Semaphore; +use tokio::{runtime::Handle, sync::Semaphore}; -use crate::error::{Error, Result}; - -use crate::large::indexer::HashedEntryAddress; -use crate::large::{ - scanner::{EntryInfo, RegionScanner}, - serde::{AtomicSequence, Sequence}, +use super::{ + generic::GenericLargeStorageConfig, + indexer::{EntryAddress, Indexer}, +}; +use crate::{ + device::RegionId, + error::{Error, Result}, + large::{ + indexer::HashedEntryAddress, + scanner::{EntryInfo, RegionScanner}, + serde::{AtomicSequence, Sequence}, + tombstone::Tombstone, + }, + region::{Region, RegionManager}, }; - -use super::generic::GenericLargeStorageConfig; -use super::indexer::EntryAddress; -use super::indexer::Indexer; -use crate::device::RegionId; -use crate::large::tombstone::Tombstone; -use crate::region::{Region, RegionManager}; /// The recover mode of the disk cache. #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, ValueEnum)] diff --git a/foyer-storage/src/large/scanner.rs b/foyer-storage/src/large/scanner.rs index bd09a452..53bd15c4 100644 --- a/foyer-storage/src/large/scanner.rs +++ b/foyer-storage/src/large/scanner.rs @@ -21,6 +21,7 @@ use foyer_common::{ strict_assert, }; +use super::indexer::EntryAddress; use crate::{ device::bytes::IoBytes, error::Result, @@ -29,8 +30,6 @@ use crate::{ serde::EntryDeserializer, }; -use super::indexer::EntryAddress; - #[derive(Debug)] pub struct EntryInfo { pub hash: u64, diff --git a/foyer-storage/src/large/serde.rs b/foyer-storage/src/large/serde.rs index ab52be83..8527f2cd 100644 --- a/foyer-storage/src/large/serde.rs +++ b/foyer-storage/src/large/serde.rs @@ -12,13 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::sync::atomic::AtomicU64; + use bytes::{Buf, BufMut}; use crate::{ compress::Compression, error::{Error, Result}, }; -use std::sync::atomic::AtomicU64; const ENTRY_MAGIC: u32 = 0x97_03_27_00; const ENTRY_MAGIC_MASK: u32 = 0xFF_FF_FF_00; diff --git a/foyer-storage/src/large/tombstone.rs b/foyer-storage/src/large/tombstone.rs index ffb633d1..45040539 100644 --- a/foyer-storage/src/large/tombstone.rs +++ b/foyer-storage/src/large/tombstone.rs @@ -29,11 +29,10 @@ use crate::{ monitor::{Monitored, MonitoredOptions}, Dev, DevExt, RegionId, }, + error::{Error, Result}, IoBytesMut, }; -use crate::error::{Error, Result}; - /// The configurations for the tombstone log. #[derive(Debug, Clone)] pub struct TombstoneLogConfig { @@ -308,9 +307,8 @@ mod tests { use itertools::Itertools; use tempfile::tempdir; - use crate::device::direct_fs::{DirectFsDevice, DirectFsDeviceOptionsBuilder}; - use super::*; + use crate::device::direct_fs::{DirectFsDevice, DirectFsDeviceOptionsBuilder}; #[test_log::test(tokio::test)] async fn test_tombstone_log() { diff --git a/foyer-storage/src/picker/mod.rs b/foyer-storage/src/picker/mod.rs index 0fad3925..98ff6f43 100644 --- a/foyer-storage/src/picker/mod.rs +++ b/foyer-storage/src/picker/mod.rs @@ -12,9 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{device::RegionId, region::RegionStats, statistics::Statistics}; use std::{collections::HashMap, fmt::Debug, sync::Arc}; +use crate::{device::RegionId, region::RegionStats, statistics::Statistics}; + /// The admission picker for the disk cache. pub trait AdmissionPicker: Send + Sync + 'static + Debug { /// The key type for the admission picker. diff --git a/foyer-storage/src/picker/utils.rs b/foyer-storage/src/picker/utils.rs index 71e35c21..5b3f5aee 100644 --- a/foyer-storage/src/picker/utils.rs +++ b/foyer-storage/src/picker/utils.rs @@ -25,9 +25,8 @@ use std::{ use foyer_common::{code::StorageKey, rated_ticket::RatedTicket, strict_assert}; use itertools::Itertools; -use crate::{device::RegionId, region::RegionStats, statistics::Statistics}; - use super::{AdmissionPicker, EvictionPicker, ReinsertionPicker}; +use crate::{device::RegionId, region::RegionStats, statistics::Statistics}; /// A picker that always returns `true`. pub struct AdmitAllPicker(PhantomData) diff --git a/foyer-storage/src/serde.rs b/foyer-storage/src/serde.rs index de9bcb50..fcc805cb 100644 --- a/foyer-storage/src/serde.rs +++ b/foyer-storage/src/serde.rs @@ -13,12 +13,12 @@ // limitations under the License. use std::{fmt::Debug, hash::Hasher, time::Instant}; -use twox_hash::XxHash64; use foyer_common::{ code::{StorageKey, StorageValue}, metrics::Metrics, }; +use twox_hash::XxHash64; use crate::{ compress::Compression, diff --git a/foyer-storage/src/small/generic.rs b/foyer-storage/src/small/generic.rs index 428f248d..d7e6a983 100644 --- a/foyer-storage/src/small/generic.rs +++ b/foyer-storage/src/small/generic.rs @@ -12,12 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::{fmt::Debug, marker::PhantomData, sync::Arc}; + use foyer_common::code::{HashBuilder, StorageKey, StorageValue}; use foyer_memory::CacheEntry; use futures::Future; -use std::{fmt::Debug, marker::PhantomData, sync::Arc}; - use crate::{error::Result, serde::KvInfo, storage::Storage, DeviceStats, IoBytes}; pub struct GenericSmallStorageConfig diff --git a/foyer-storage/src/storage/either.rs b/foyer-storage/src/storage/either.rs index 7ffa1440..cdc64417 100644 --- a/foyer-storage/src/storage/either.rs +++ b/foyer-storage/src/storage/either.rs @@ -12,6 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::{ + fmt::Debug, + pin::Pin, + sync::Arc, + task::{Context, Poll}, +}; + use foyer_common::code::{HashBuilder, StorageKey, StorageValue}; use foyer_memory::CacheEntry; use futures::{ @@ -21,13 +28,6 @@ use futures::{ use crate::{error::Result, serde::KvInfo, storage::Storage, DeviceStats, IoBytes}; -use std::{ - fmt::Debug, - pin::Pin, - sync::Arc, - task::{Context, Poll}, -}; - enum OrderFuture { LeftFirst(F1), RightFirst(F2), diff --git a/foyer-storage/src/storage/noop.rs b/foyer-storage/src/storage/noop.rs index 9d44d665..dc9a9f25 100644 --- a/foyer-storage/src/storage/noop.rs +++ b/foyer-storage/src/storage/noop.rs @@ -12,20 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::sync::Arc; -use std::{fmt::Debug, future::Future, marker::PhantomData}; +use std::{fmt::Debug, future::Future, marker::PhantomData, sync::Arc}; use foyer_common::code::{HashBuilder, StorageKey, StorageValue}; use foyer_memory::CacheEntry; - use futures::future::ready; -use crate::device::monitor::DeviceStats; -use crate::serde::KvInfo; -use crate::storage::Storage; - -use crate::error::Result; -use crate::IoBytes; +use crate::{device::monitor::DeviceStats, error::Result, serde::KvInfo, storage::Storage, IoBytes}; pub struct Noop where diff --git a/foyer-storage/src/store.rs b/foyer-storage/src/store.rs index 82cfcb99..28708004 100644 --- a/foyer-storage/src/store.rs +++ b/foyer-storage/src/store.rs @@ -12,6 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::{borrow::Borrow, fmt::Debug, hash::Hash, marker::PhantomData, sync::Arc, time::Instant}; + +use ahash::RandomState; +use foyer_common::{ + code::{HashBuilder, StorageKey, StorageValue}, + metrics::Metrics, + runtime::BackgroundShutdownRuntime, +}; +use foyer_memory::{Cache, CacheEntry}; +use serde::{Deserialize, Serialize}; +use tokio::runtime::Handle; + use crate::{ compress::Compression, device::{ @@ -35,16 +47,6 @@ use crate::{ }, Dev, DevExt, DirectFileDeviceOptions, IoBytesMut, }; -use ahash::RandomState; -use foyer_common::{ - code::{HashBuilder, StorageKey, StorageValue}, - metrics::Metrics, - runtime::BackgroundShutdownRuntime, -}; -use foyer_memory::{Cache, CacheEntry}; -use serde::{Deserialize, Serialize}; -use std::{borrow::Borrow, fmt::Debug, hash::Hash, marker::PhantomData, sync::Arc, time::Instant}; -use tokio::runtime::Handle; /// The disk cache engine that serves as the storage backend of `foyer`. pub struct Store diff --git a/foyer/src/hybrid/cache.rs b/foyer/src/hybrid/cache.rs index ffc497f7..d4a6c126 100644 --- a/foyer/src/hybrid/cache.rs +++ b/foyer/src/hybrid/cache.rs @@ -41,9 +41,8 @@ use futures::FutureExt; use pin_project::pin_project; use tokio::sync::oneshot; -use crate::HybridCacheWriter; - use super::writer::HybridCacheStorageWriter; +use crate::HybridCacheWriter; macro_rules! root_span { ($self:ident, mut $name:ident, $label:expr) => { diff --git a/foyer/src/hybrid/writer.rs b/foyer/src/hybrid/writer.rs index 71943eab..3d040594 100644 --- a/foyer/src/hybrid/writer.rs +++ b/foyer/src/hybrid/writer.rs @@ -12,14 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -use ahash::RandomState; -use foyer_common::code::{HashBuilder, StorageKey, StorageValue}; -use foyer_memory::CacheContext; use std::{ fmt::Debug, time::{Duration, Instant}, }; +use ahash::RandomState; +use foyer_common::code::{HashBuilder, StorageKey, StorageValue}; +use foyer_memory::CacheContext; + use crate::{HybridCache, HybridCacheEntry}; /// Writer for hybrid cache to support more flexible write APIs. @@ -90,7 +91,8 @@ where /// Check if the entry can be admitted by the admission picker of the disk cache. /// - /// `pick` is idempotent (unless `force` is called). Which means the disk cache only check its admission at most once. + /// `pick` is idempotent (unless `force` is called). Which means the disk cache only check its admission at most + /// once. pub fn pick(&mut self) -> bool { if let Some(picked) = self.picked { return picked; diff --git a/foyer/src/prelude.rs b/foyer/src/prelude.rs index 06dc78d1..a3a6cd67 100644 --- a/foyer/src/prelude.rs +++ b/foyer/src/prelude.rs @@ -12,12 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::common; -use crate::memory; -use crate::storage; - use ahash::RandomState; - pub use common::{ buf::{BufExt, BufMutExt}, code::{Key, StorageKey, StorageValue, Value}, @@ -39,6 +34,7 @@ pub use crate::hybrid::{ cache::{HybridCache, HybridCacheEntry, HybridFetch, HybridFetchInner}, writer::{HybridCacheStorageWriter, HybridCacheWriter}, }; +use crate::{common, memory, storage}; /// In-memory cache. pub type Cache = memory::Cache; diff --git a/rustfmt.nightly.toml b/rustfmt.nightly.toml new file mode 100644 index 00000000..cff9a922 --- /dev/null +++ b/rustfmt.nightly.toml @@ -0,0 +1,8 @@ +# TODO(MrCroxx): Move features into `rustfmt.toml` after stable. + +imports_granularity = "Crate" # unsatble +group_imports = "StdExternalCrate" # unstable +tab_spaces = 4 +wrap_comments = true # unstable +max_width = 120 +comment_width = 120 # unstable diff --git a/rustfmt.toml b/rustfmt.toml index 16bafd46..719d3407 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1,8 +1,2 @@ -# TODO(MrCroxx): Restore comments after the features are stable. - -# imports_granularity = "Crate" -# group_imports = "StdExternalCrate" tab_spaces = 4 -# wrap_comments = true max_width = 120 -# comment_width = 120 From 48d5bcafdea9cf27b737de0d60aa757d72642350 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A7=9A=E5=86=9B?= Date: Wed, 28 Aug 2024 00:35:14 +0800 Subject: [PATCH 06/40] chore: fix spelling errors in comments (#670) --- foyer-memory/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/foyer-memory/src/lib.rs b/foyer-memory/src/lib.rs index 47df1c63..036ffb3f 100644 --- a/foyer-memory/src/lib.rs +++ b/foyer-memory/src/lib.rs @@ -26,13 +26,13 @@ //! //! # Design //! -//! The cache is mainly compused of the following components: +//! The cache is mainly composed of the following components: //! 1. handle : Carries the cached entry, reference count, pointer links in the eviction container, etc. //! 2. indexer : Indexes cached keys to the handles. //! 3. eviction container : Defines the order of eviction. Usually implemented with intrusive data structures. //! //! Because a handle needs to be referenced and mutated by both the indexer and the eviction container in the same -//! thread, it is hard to implement in 100% safe Rust without overhead. So, the APIs of the indexer and the eviciton +//! thread, it is hard to implement in 100% safe Rust without overhead. So, the APIs of the indexer and the eviction //! container are defined with `NonNull` pointers of the handles. //! //! When some entry is inserted into the cache, the associated handle should be transmuted into pointer without From 1f9ea31995d39d31182bf66876d08bf7017c9450 Mon Sep 17 00:00:00 2001 From: Croxx Date: Wed, 28 Aug 2024 11:52:30 +0800 Subject: [PATCH 07/40] chore: fix more typos (#671) Signed-off-by: MrCroxx --- CHANGELOG.md | 12 ++++++------ foyer/src/hybrid/builder.rs | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f8a355b..474e1dad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,7 @@ - Expose `Weighter` trait. - Support `serde` for more configurations. - Update `foyer-bench` with more fine-grained configurations. -- Fix panices with `None` recover mode. +- Fix panics with `None` recover mode. @@ -130,7 +130,7 @@ ### Changes -- Hybird cache `fetch()` use the dedicated runtime by default if enabled. +- Hybrid cache `fetch()` use the dedicated runtime by default if enabled. - Separate `fetch()` and `fetch_with_runtime()` interface for in-memory cache. @@ -254,7 +254,7 @@ ### Changes -- feat: Impl `Debug` for `HybirdCache`. +- feat: Impl `Debug` for `HybridCache`. - feat: Impl `serde`, `Default` for eviction configs. - refactor: Add internal trait `EvictionConfig` to bound eviction algorithm configs. @@ -298,7 +298,7 @@ ### Changes -- Fix `FsDeviceBuilder` on a non-exist directory without cacpacity given. +- Fix `FsDeviceBuilder` on a non-exist directory without capacity given. @@ -663,7 +663,7 @@ The implementation of **foyer** is separated into multiple crates. But importing Brief description about the subcrates: - foyer-common: Provide basic data structures and algorithms. -- foyer-intrusive: Provide intrusive containers for implementing eviction lists and collections. Intrisive data structures provide the ability to implement low-cost multi-index data structures, which will be used for the memory cache in future. +- foyer-intrusive: Provide intrusive containers for implementing eviction lists and collections. Intrusive data structures provide the ability to implement low-cost multi-index data structures, which will be used for the memory cache in future. - foyer-storage: Provide the file cache storage engine and wrappers to simplify the code. - foyer-storage-bench: Runnable benchmark tool for the file cache storage engine. - foyer-workspace-hack: Generated by [hakari](https://crates.io/crates/hakari) to prevent building each crate from triggering building from scratch. @@ -679,6 +679,6 @@ Brief description about the subcrates:
-Initial version with just bacis interfaces. +Initial version with just basic interfaces.
diff --git a/foyer/src/hybrid/builder.rs b/foyer/src/hybrid/builder.rs index 53c2dceb..fe104b0b 100644 --- a/foyer/src/hybrid/builder.rs +++ b/foyer/src/hybrid/builder.rs @@ -185,7 +185,7 @@ where } } -/// Hybird cache builder modify the disk cache configurations. +/// Hybrid cache builder modify the disk cache configurations. pub struct HybridCacheBuilderPhaseStorage where K: StorageKey, From 9c6877be3e09292c7cedaeec30de8db36e7e46a8 Mon Sep 17 00:00:00 2001 From: Croxx Date: Thu, 29 Aug 2024 12:25:39 +0800 Subject: [PATCH 08/40] perf: refine `fetch` runtime usage (#668) * perf: refine `fetch` runtime usage Signed-off-by: MrCroxx * chore: fix some comments Signed-off-by: MrCroxx * chore: fix typo Signed-off-by: MrCroxx --------- Signed-off-by: MrCroxx --- foyer/src/hybrid/builder.rs | 2 +- foyer/src/hybrid/cache.rs | 22 +++++++++++++--------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/foyer/src/hybrid/builder.rs b/foyer/src/hybrid/builder.rs index fe104b0b..3ee2a450 100644 --- a/foyer/src/hybrid/builder.rs +++ b/foyer/src/hybrid/builder.rs @@ -338,7 +338,7 @@ where /// The eviction pickers are applied in order. If the previous eviction picker doesn't pick any region, the next one /// will be applied. /// - /// If no eviction picker pickes a region, a region will be picked randomly. + /// If no eviction picker picks a region, a region will be picked randomly. /// /// Default: [ invalid ratio picker { threshold = 0.8 }, fifo picker ] pub fn with_eviction_pickers(self, eviction_pickers: Vec>) -> Self { diff --git a/foyer/src/hybrid/cache.rs b/foyer/src/hybrid/cache.rs index d4a6c126..e132d982 100644 --- a/foyer/src/hybrid/cache.rs +++ b/foyer/src/hybrid/cache.rs @@ -257,7 +257,7 @@ where /// Get cached entry with the given key from the hybrid cache. /// - /// Different from `get`, `obtain` dedeplicates the disk cache queries. + /// Different from `get`, `obtain` deduplicates the disk cache queries. /// /// `obtain` is always supposed to be used instead of `get` if the overhead of getting the ownership of the given /// key is acceptable. @@ -485,6 +485,7 @@ where context, || { let metrics = self.metrics.clone(); + let user_runtime_handle = self.storage().runtimes().user_runtime_handle.clone(); async move { match store.load(&key).await.map_err(anyhow::Error::from) { @@ -501,17 +502,20 @@ where metrics.hybrid_miss.increment(1); metrics.hybrid_miss_duration.record(now.elapsed()); - future - .map(|res| Diversion { - target: res, - store: Some(FetchMark), - }) - .in_span(Span::enter_with_local_parent("foyer::hybrid::fetch::fn")) + user_runtime_handle + .spawn( + future + .map(|res| Diversion { + target: res, + store: Some(FetchMark), + }) + .in_span(Span::enter_with_local_parent("foyer::hybrid::fetch::fn")), + ) .await + .unwrap() } }, - // TODO(MrCroxx): check regression - self.storage().runtimes().user_runtime_handle, + self.storage().runtimes().read_runtime_handle, ); if inner.state() == FetchState::Hit { From f8eae8cb1f87ab20a6f4a2956f15156242296c34 Mon Sep 17 00:00:00 2001 From: Croxx Date: Thu, 29 Aug 2024 14:02:57 +0800 Subject: [PATCH 09/40] feat: impl Default for TokioRuntimeConfig (#672) Signed-off-by: MrCroxx --- foyer-storage/src/store.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/foyer-storage/src/store.rs b/foyer-storage/src/store.rs index 28708004..db5cbef1 100644 --- a/foyer-storage/src/store.rs +++ b/foyer-storage/src/store.rs @@ -296,7 +296,7 @@ impl CombinedConfig { } /// Tokio runtime configuration. -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Default, Serialize, Deserialize)] pub struct TokioRuntimeConfig { /// Dedicated runtime worker threads. /// From 44c0dc938c9f3778b808402c4e86b1bca8fe8a21 Mon Sep 17 00:00:00 2001 From: Croxx Date: Thu, 29 Aug 2024 17:41:50 +0800 Subject: [PATCH 10/40] fix: fix build with madsim (#673) Signed-off-by: MrCroxx --- foyer-common/src/asyncify.rs | 8 +++++++- foyer-storage/Cargo.toml | 3 +++ foyer-storage/src/store.rs | 2 ++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/foyer-common/src/asyncify.rs b/foyer-common/src/asyncify.rs index a5bb777a..9dacfb5b 100644 --- a/foyer-common/src/asyncify.rs +++ b/foyer-common/src/asyncify.rs @@ -25,6 +25,9 @@ where } #[cfg(madsim)] +/// Convert the block call to async call. +/// +/// madsim compatible mode. pub async fn asyncify(f: F) -> T where F: FnOnce() -> T + Send + 'static, @@ -33,7 +36,7 @@ where f() } -/// Convert the block call to async call. +/// Convert the block call to async call with given runtime. #[cfg(not(madsim))] pub async fn asyncify_with_runtime(runtime: &Handle, f: F) -> T where @@ -44,6 +47,9 @@ where } #[cfg(madsim)] +/// Convert the block call to async call with given runtime. +/// +/// madsim compatible mode. pub async fn asyncify_with_runtime(_: &Handle, f: F) -> T where F: FnOnce() -> T + Send + 'static, diff --git a/foyer-storage/Cargo.toml b/foyer-storage/Cargo.toml index bb37deb5..d633aa8a 100644 --- a/foyer-storage/Cargo.toml +++ b/foyer-storage/Cargo.toml @@ -54,3 +54,6 @@ strict_assertions = [ "foyer-memory/strict_assertions", ] mtrace = ["fastrace/enable", "foyer-common/mtrace", "foyer-memory/mtrace"] + +[lints.rust] +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(madsim)'] } diff --git a/foyer-storage/src/store.rs b/foyer-storage/src/store.rs index db5cbef1..7fb658ea 100644 --- a/foyer-storage/src/store.rs +++ b/foyer-storage/src/store.rs @@ -571,9 +571,11 @@ where let build_runtime = |config: &TokioRuntimeConfig, suffix: &str| { let mut builder = tokio::runtime::Builder::new_multi_thread(); + #[cfg(not(madsim))] if config.worker_threads != 0 { builder.worker_threads(config.worker_threads); } + #[cfg(not(madsim))] if config.max_blocking_threads != 0 { builder.max_blocking_threads(config.max_blocking_threads); } From ac4c0a56135d2e6944658b4009c7e0284cf7f1b7 Mon Sep 17 00:00:00 2001 From: Croxx Date: Thu, 29 Aug 2024 22:24:14 +0800 Subject: [PATCH 11/40] fix: no panic on zero length entry (#674) Signed-off-by: MrCroxx --- foyer-storage/src/large/flusher.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/foyer-storage/src/large/flusher.rs b/foyer-storage/src/large/flusher.rs index 2cef53c7..af523dfe 100644 --- a/foyer-storage/src/large/flusher.rs +++ b/foyer-storage/src/large/flusher.rs @@ -190,7 +190,7 @@ where return; } }; - strict_assert!(allocation.len() > header.entry_len()); + strict_assert!(allocation.len() >= header.entry_len()); header.write(&mut allocation[0..EntryHeader::serialized_len()]); allocation[EntryHeader::serialized_len()..header.entry_len()].copy_from_slice(&buffer); From 7eeb783020a4dad5b11382fdfc36ad62f7d69939 Mon Sep 17 00:00:00 2001 From: Croxx Date: Fri, 30 Aug 2024 00:36:12 +0800 Subject: [PATCH 12/40] fix: fix panic on scanner overflow (#677) * fix: fix panic on scanner overflow Signed-off-by: MrCroxx * chore: make ffmt happy Signed-off-by: MrCroxx --------- Signed-off-by: MrCroxx --- foyer-storage/src/error.rs | 13 +++++- foyer-storage/src/large/scanner.rs | 73 +++++++++++++++++++++++++++--- foyer-storage/src/region.rs | 7 +++ 3 files changed, 85 insertions(+), 8 deletions(-) diff --git a/foyer-storage/src/error.rs b/foyer-storage/src/error.rs index db44d1b4..d858a5ae 100644 --- a/foyer-storage/src/error.rs +++ b/foyer-storage/src/error.rs @@ -12,7 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::fmt::{Debug, Display}; +use std::{ + fmt::{Debug, Display}, + ops::Range, +}; /// Disk cache error type. #[derive(thiserror::Error, Debug)] @@ -42,6 +45,14 @@ pub enum Error { /// Gotten checksum. get: u64, }, + /// Out of range. + #[error("out of range, valid: {valid:?}, get: {get:?}")] + OutOfRange { + /// Valid range. + valid: Range, + /// Gotten range. + get: Range, + }, /// Other error. #[error(transparent)] Other(#[from] anyhow::Error), diff --git a/foyer-storage/src/large/scanner.rs b/foyer-storage/src/large/scanner.rs index 53bd15c4..f735f26c 100644 --- a/foyer-storage/src/large/scanner.rs +++ b/foyer-storage/src/large/scanner.rs @@ -24,7 +24,7 @@ use foyer_common::{ use super::indexer::EntryAddress; use crate::{ device::bytes::IoBytes, - error::Result, + error::{Error, Result}, large::serde::{EntryHeader, Sequence}, region::Region, serde::EntryDeserializer, @@ -38,13 +38,13 @@ pub struct EntryInfo { } #[derive(Debug)] -struct CachedDeviceReader { +struct CachedRegionReader { region: Region, offset: u64, buffer: IoBytes, } -impl CachedDeviceReader { +impl CachedRegionReader { const IO_SIZE_HINT: usize = 16 * 1024; fn new(region: Region) -> Self { @@ -56,20 +56,30 @@ impl CachedDeviceReader { } async fn read(&mut self, offset: u64, len: usize) -> Result<&[u8]> { + if offset as usize + len >= self.region.size() { + return Err(Error::OutOfRange { + valid: 0..self.region.size(), + get: offset as usize..offset as usize + len, + }); + } + if offset >= self.offset && offset as usize + len <= self.offset as usize + self.buffer.len() { let start = (offset - self.offset) as usize; let end = start + len; return Ok(&self.buffer[start..end]); } + + // Move forward. self.offset = bits::align_down(self.region.align() as u64, offset); let end = bits::align_up( self.region.align(), std::cmp::max(offset as usize + len, offset as usize + Self::IO_SIZE_HINT), ); let end = std::cmp::min(self.region.size(), end); + let read_len = end - self.offset as usize; - strict_assert!(bits::is_aligned(self.region.align(), read_len)); - strict_assert!(read_len >= len); + assert!(bits::is_aligned(self.region.align(), read_len)); + assert!(read_len >= len); let buffer = self.region.read(self.offset, read_len).await?.freeze(); self.buffer = buffer; @@ -84,13 +94,13 @@ impl CachedDeviceReader { pub struct RegionScanner { region: Region, offset: u64, - cache: CachedDeviceReader, + cache: CachedRegionReader, metrics: Arc, } impl RegionScanner { pub fn new(region: Region, metrics: Arc) -> Self { - let cache = CachedDeviceReader::new(region.clone()); + let cache = CachedRegionReader::new(region.clone()); Self { region, offset: 0, @@ -228,3 +238,52 @@ impl RegionScanner { Ok(Some((info, key, value))) } } + +#[cfg(test)] +mod tests { + use std::path::Path; + + use super::*; + use crate::{ + device::{ + monitor::{Monitored, MonitoredOptions}, + Dev, MonitoredDevice, + }, + region::RegionStats, + DirectFsDeviceOptions, + }; + + const KB: usize = 1024; + + async fn device_for_test(dir: impl AsRef) -> MonitoredDevice { + Monitored::open(MonitoredOptions { + options: DirectFsDeviceOptions { + dir: dir.as_ref().into(), + capacity: 64 * KB, + file_size: 16 * KB, + } + .into(), + metrics: Arc::new(Metrics::new("test")), + }) + .await + .unwrap() + } + + #[tokio::test] + async fn test_cached_region_reader_overflow() { + let dir = tempfile::tempdir().unwrap(); + + let device = device_for_test(dir.path()).await; + let region = Region::new_for_test(0, device, Arc::::default()); + + let mut cached = CachedRegionReader::new(region.clone()); + + cached.read(0, region.size() / 2).await.unwrap(); + let res = cached.read(region.size() as u64 / 2, region.size()).await; + assert!( + matches!(res, Err(Error::OutOfRange { valid, get }) if valid == (0..region.size()) && get == ( + region.size() / 2..region.size() / 2 + region.size() + )) + ); + } +} diff --git a/foyer-storage/src/region.rs b/foyer-storage/src/region.rs index bb99d82f..ee55ac3f 100644 --- a/foyer-storage/src/region.rs +++ b/foyer-storage/src/region.rs @@ -105,6 +105,13 @@ impl Region { } } +#[cfg(test)] +impl Region { + pub fn new_for_test(id: RegionId, device: MonitoredDevice, stats: Arc) -> Self { + Self { id, device, stats } + } +} + #[derive(Clone)] pub struct RegionManager { inner: Arc, From f2f80cf871c0a4bd34b8dbb54e10c5193f2b97dd Mon Sep 17 00:00:00 2001 From: Croxx Date: Fri, 30 Aug 2024 12:51:01 +0800 Subject: [PATCH 13/40] fix: hide unnecessary error on load error (#679) * fix: hide unnecessary error on load error Signed-off-by: MrCroxx * chore: fix ffmt Signed-off-by: MrCroxx --------- Signed-off-by: MrCroxx --- foyer-storage/src/compress.rs | 7 ++-- foyer-storage/src/error.rs | 5 ++- foyer-storage/src/large/generic.rs | 63 ++++++++++++++++++++++++------ foyer-storage/src/large/serde.rs | 22 +++++------ 4 files changed, 68 insertions(+), 29 deletions(-) diff --git a/foyer-storage/src/compress.rs b/foyer-storage/src/compress.rs index 2aa78e38..29f3448b 100644 --- a/foyer-storage/src/compress.rs +++ b/foyer-storage/src/compress.rs @@ -14,11 +14,10 @@ // TODO(MrCroxx): unify compress interface? -use anyhow::anyhow; use clap::ValueEnum; use serde::{Deserialize, Serialize}; -const NOT_SUPPORT: &str = "compression algorithm not support"; +use crate::error::Error; /// The compression algorithm of the disk cache. #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, ValueEnum)] @@ -53,14 +52,14 @@ impl From for u8 { } impl TryFrom for Compression { - type Error = anyhow::Error; + type Error = Error; fn try_from(value: u8) -> Result { match value { 0 => Ok(Self::None), 1 => Ok(Self::Zstd), 2 => Ok(Self::Lz4), - _ => Err(anyhow!(NOT_SUPPORT)), + _ => Err(Error::CompressionAlgorithmNotSupported(value)), } } } diff --git a/foyer-storage/src/error.rs b/foyer-storage/src/error.rs index d858a5ae..87442e15 100644 --- a/foyer-storage/src/error.rs +++ b/foyer-storage/src/error.rs @@ -30,7 +30,7 @@ pub enum Error { /// Multiple error list. Multiple(MultipleError), /// Entry magic mismatch. - #[error("magiac mismatch, expected: {expected}, get: {get}")] + #[error("magic mismatch, expected: {expected}, get: {get}")] MagicMismatch { /// Expected magic. expected: u32, @@ -53,6 +53,9 @@ pub enum Error { /// Gotten range. get: Range, }, + /// Compression algorithm not supported. + #[error("compression algorithm not supported: {0}")] + CompressionAlgorithmNotSupported(u8), /// Other error. #[error(transparent)] Other(#[from] anyhow::Error), diff --git a/foyer-storage/src/large/generic.rs b/foyer-storage/src/large/generic.rs index 597adcd0..f19fec4c 100644 --- a/foyer-storage/src/large/generic.rs +++ b/foyer-storage/src/large/generic.rs @@ -337,7 +337,19 @@ where .cache_read_bytes .fetch_add(bits::align_up(device.align(), buffer.len()), Ordering::Relaxed); - let header = EntryHeader::read(&buffer[..EntryHeader::serialized_len()])?; + let header = match EntryHeader::read(&buffer[..EntryHeader::serialized_len()]) { + Ok(header) => header, + Err(e @ Error::MagicMismatch { .. }) + | Err(e @ Error::ChecksumMismatch { .. }) + | Err(e @ Error::CompressionAlgorithmNotSupported(_)) => { + tracing::trace!("deserialize entry header error: {e}, remove this entry and skip"); + indexer.remove(hash); + metrics.storage_miss.increment(1); + metrics.storage_miss_duration.record(now.elapsed()); + return Ok(None); + } + Err(e) => return Err(e), + }; let (k, v) = match EntryDeserializer::deserialize::( &buffer[EntryHeader::serialized_len()..], @@ -348,16 +360,14 @@ where &metrics, ) { Ok(res) => res, - Err(e) => match e { - Error::MagicMismatch { .. } | Error::ChecksumMismatch { .. } => { - tracing::trace!("deserialize read buffer raise error: {e}, remove this entry and skip"); - indexer.remove(hash); - metrics.storage_miss.increment(1); - metrics.storage_miss_duration.record(now.elapsed()); - return Ok(None); - } - e => return Err(e), - }, + Err(e @ Error::MagicMismatch { .. }) | Err(e @ Error::ChecksumMismatch { .. }) => { + tracing::trace!("deserialize read buffer raise error: {e}, remove this entry and skip"); + indexer.remove(hash); + metrics.storage_miss.increment(1); + metrics.storage_miss_duration.record(now.elapsed()); + return Ok(None); + } + Err(e) => return Err(e), }; metrics.storage_hit.increment(1); @@ -484,7 +494,7 @@ where #[cfg(test)] mod tests { - use std::path::Path; + use std::{fs::File, os::unix::fs::FileExt, path::Path}; use ahash::RandomState; use foyer_memory::{Cache, CacheBuilder, FifoConfig}; @@ -912,4 +922,33 @@ mod tests { ] ); } + + #[test_log::test(tokio::test)] + async fn test_store_magic_checksum_mismatch() { + let dir = tempfile::tempdir().unwrap(); + + let memory = cache_for_test(); + let store = store_for_test(dir.path()).await; + + // write entry 1 + let e1 = memory.insert(1, vec![1; 7 * KB]); + enqueue(&store, e1); + store.wait().await; + + // check entry 1 + let r1 = store.load(memory.hash(&1)).await.unwrap().unwrap(); + assert_eq!(r1, (1, vec![1; 7 * KB])); + + // corrupt entry and header + for entry in std::fs::read_dir(dir.path()).unwrap() { + let entry = entry.unwrap(); + if !entry.metadata().unwrap().is_file() { + continue; + } + let file = File::options().write(true).open(entry.path()).unwrap(); + file.write_all_at(&[b'x'; 4 * 1024], 0).unwrap(); + } + + assert!(store.load(memory.hash(&1)).await.unwrap().is_none()); + } } diff --git a/foyer-storage/src/large/serde.rs b/foyer-storage/src/large/serde.rs index 8527f2cd..03ea69e1 100644 --- a/foyer-storage/src/large/serde.rs +++ b/foyer-storage/src/large/serde.rs @@ -65,18 +65,8 @@ impl EntryHeader { let checksum = buf.get_u64(); let v = buf.get_u32(); - let compression = Compression::try_from(v as u8)?; - - let this = Self { - key_len, - value_len, - hash, - sequence, - compression, - checksum, - }; - tracing::trace!("{this:#?}"); + tracing::trace!("read entry header, key len: {key_len}, value_len: {value_len}, hash: {hash}, sequence: {sequence}, checksum: {checksum}, extra: {v}"); let magic = v & ENTRY_MAGIC_MASK; if magic != ENTRY_MAGIC { @@ -85,7 +75,15 @@ impl EntryHeader { get: magic, }); } + let compression = Compression::try_from(v as u8)?; - Ok(this) + Ok(Self { + key_len, + value_len, + hash, + sequence, + checksum, + compression, + }) } } From 46d76a52c94d15b5954d3d871d073c7540388396 Mon Sep 17 00:00:00 2001 From: Croxx Date: Fri, 30 Aug 2024 16:56:53 +0800 Subject: [PATCH 14/40] chore: move compact bloom filter to utils, fix typos (#680) Signed-off-by: MrCroxx --- examples/tail_based_tracing.rs | 2 +- foyer-bench/src/main.rs | 6 +++--- foyer-common/Cargo.toml | 2 -- foyer-common/src/bits.rs | 6 +++--- foyer-common/src/lib.rs | 2 -- foyer-common/src/object_pool.rs | 4 ++-- foyer-common/src/range.rs | 1 - foyer-common/src/wait_group.rs | 8 ++++---- foyer-intrusive/src/adapter.rs | 4 ++-- foyer-memory/benches/bench_dynamic_dispatch.rs | 2 +- foyer-memory/src/context.rs | 2 +- foyer-memory/src/eviction/lfu.rs | 4 ++-- foyer-memory/src/eviction/mod.rs | 4 ++-- foyer-memory/src/generic.rs | 2 +- foyer-memory/src/handle.rs | 14 +++++++------- foyer-memory/src/lib.rs | 2 +- foyer-storage/src/compress.rs | 4 ++-- foyer-storage/src/device/bytes.rs | 2 +- foyer-storage/src/large/batch.rs | 2 +- foyer-storage/src/large/reclaimer.rs | 2 +- foyer-storage/src/large/tombstone.rs | 4 ++-- foyer-storage/src/picker/utils.rs | 2 +- foyer-storage/src/region.rs | 6 +++--- foyer-storage/src/store.rs | 4 ++-- foyer-storage/src/test_utils.rs | 6 +++--- foyer-util/Cargo.toml | 2 ++ .../src/compact_bloom_filter.rs | 8 ++++---- foyer-util/src/lib.rs | 1 + 28 files changed, 53 insertions(+), 55 deletions(-) rename {foyer-common => foyer-util}/src/compact_bloom_filter.rs (97%) diff --git a/examples/tail_based_tracing.rs b/examples/tail_based_tracing.rs index 79c7eef7..e74a0cef 100644 --- a/examples/tail_based_tracing.rs +++ b/examples/tail_based_tracing.rs @@ -58,7 +58,7 @@ fn init_exporter() { init_opentelemetry_exporter(); #[cfg(not(any(feature = "jaeger", feature = "ot")))] - panic!("Either jeager or opentelemetry feature must be enabled!"); + panic!("Either jaeger or opentelemetry feature must be enabled!"); } /// NOTE: To run this example, please enable feature "mtrace" and either "jaeger" or "ot". diff --git a/foyer-bench/src/main.rs b/foyer-bench/src/main.rs index f24b8547..70f9f3af 100644 --- a/foyer-bench/src/main.rs +++ b/foyer-bench/src/main.rs @@ -138,9 +138,9 @@ pub struct Args { #[arg(long, default_value_t = 0)] admission_rate_limit: usize, - /// Enable rated ticket reinsetion picker if `reinseriton_rate_limit > 0`. (MiB/s) + /// Enable rated ticket reinsertion picker if `reinsertion_rate_limit > 0`. (MiB/s) #[arg(long, default_value_t = 0)] - reinseriton_rate_limit: usize, + reinsertion_rate_limit: usize, /// `0` means use default. #[arg(long, default_value_t = 0)] @@ -539,7 +539,7 @@ async fn benchmark(args: Args) { builder = builder.with_admission_picker(Arc::new(RateLimitPicker::new(args.admission_rate_limit * MIB as usize))); } - if args.reinseriton_rate_limit > 0 { + if args.reinsertion_rate_limit > 0 { builder = builder.with_reinsertion_picker(Arc::new(RateLimitPicker::new(args.admission_rate_limit * MIB as usize))); } diff --git a/foyer-common/Cargo.toml b/foyer-common/Cargo.toml index 44ae7422..c4c8ae36 100644 --- a/foyer-common/Cargo.toml +++ b/foyer-common/Cargo.toml @@ -11,7 +11,6 @@ readme = "../README.md" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -bitvec = "1" bytes = "1" cfg-if = "1" crossbeam = "0.8" @@ -23,7 +22,6 @@ metrics = { workspace = true } nix = { version = "0.29", features = ["fs"] } parking_lot = { version = "0.12", features = ["arc_lock"] } pin-project = "1" -rustversion = "1.0" serde = { workspace = true } tokio = { workspace = true } diff --git a/foyer-common/src/bits.rs b/foyer-common/src/bits.rs index 1e39c0ec..0cc7c86b 100644 --- a/foyer-common/src/bits.rs +++ b/foyer-common/src/bits.rs @@ -94,7 +94,7 @@ pub fn debug_assert_pow2(v: U) { debug_assert_eq!(v & (v - U::from(1)), U::from(0), "v: {}", v); } -/// Check if the given value is aligend with the given align. +/// Check if the given value is aligned with the given align. /// /// Note: The given align must be a power of 2. #[inline(always)] @@ -103,7 +103,7 @@ pub fn is_aligned(align: U, v: U) -> bool { v & (align - U::from(1)) == U::from(0) } -/// Assert that the given value is aligend with the given align. +/// Assert that the given value is aligned with the given align. /// /// Note: The given align must be a power of 2. #[inline(always)] @@ -112,7 +112,7 @@ pub fn assert_aligned(align: U, v: U) { assert!(is_aligned(align, v), "align: {}, v: {}", align, v); } -/// Debug assert that the given value is aligend with the given align. +/// Debug assert that the given value is aligned with the given align. /// /// Note: The given align must be a power of 2. #[inline(always)] diff --git a/foyer-common/src/lib.rs b/foyer-common/src/lib.rs index 95228f8d..bf8f6884 100644 --- a/foyer-common/src/lib.rs +++ b/foyer-common/src/lib.rs @@ -26,8 +26,6 @@ pub mod bits; pub mod buf; /// The trait for the key and value encoding and decoding. pub mod code; -/// Bloom filters. -pub mod compact_bloom_filter; /// A concurrent count down util. pub mod countdown; /// Components for monitoring internal events. diff --git a/foyer-common/src/object_pool.rs b/foyer-common/src/object_pool.rs index 45f550f7..673030e9 100644 --- a/foyer-common/src/object_pool.rs +++ b/foyer-common/src/object_pool.rs @@ -58,7 +58,7 @@ impl ObjectPool { Self { inner: Arc::new(inner) } } - /// Get or create an object from the objcet pool. + /// Get or create an object from the object pool. pub fn acquire(&self) -> T { match self.inner.queue.as_ref() { Some(queue) => queue.pop().unwrap_or((self.inner.create)()), @@ -66,7 +66,7 @@ impl ObjectPool { } } - /// Give back or release an object from the objcet pool. + /// Give back or release an object from the object pool. pub fn release(&self, item: T) { if let Some(queue) = self.inner.queue.as_ref() { let _ = queue.push(item); diff --git a/foyer-common/src/range.rs b/foyer-common/src/range.rs index 033ccb38..34d23aa4 100644 --- a/foyer-common/src/range.rs +++ b/foyer-common/src/range.rs @@ -113,7 +113,6 @@ pub trait RangeBoundsExt< } /// Map the range with the given method. - #[rustversion::since(1.77.2)] fn map(&self, f: F) -> (Bound, Bound) where F: Fn(&T) -> R, diff --git a/foyer-common/src/wait_group.rs b/foyer-common/src/wait_group.rs index c6bd1f28..855dee63 100644 --- a/foyer-common/src/wait_group.rs +++ b/foyer-common/src/wait_group.rs @@ -48,7 +48,7 @@ impl WaitGroup { pub fn wait(self) -> WaitGroupFuture { WaitGroupFuture { inner: self.inner, - inited: false, + initialized: false, } } } @@ -78,15 +78,15 @@ impl Drop for WaitGroupGuard { #[derive(Debug)] pub struct WaitGroupFuture { inner: Arc, - inited: bool, + initialized: bool, } impl Future for WaitGroupFuture { type Output = (); fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - if !self.inited { - self.inited = true; + if !self.initialized { + self.initialized = true; self.inner.waker.register(cx.waker()); } diff --git a/foyer-intrusive/src/adapter.rs b/foyer-intrusive/src/adapter.rs index 23e038fb..25063921 100644 --- a/foyer-intrusive/src/adapter.rs +++ b/foyer-intrusive/src/adapter.rs @@ -42,7 +42,7 @@ pub trait Link: Send + Sync + 'static + Default + Debug { /// /// Pointer operations MUST be valid. /// -/// [`Adapter`] is recommended to be generated by macro `instrusive_adapter!`. +/// [`Adapter`] is recommended to be generated by macro `intrusive_adapter!`. pub unsafe trait Adapter: Send + Sync + Debug + 'static { /// Item type for the adapter. type Item: ?Sized; @@ -63,7 +63,7 @@ pub unsafe trait Adapter: Send + Sync + Debug + 'static { unsafe fn ptr2link(&self, item: std::ptr::NonNull) -> std::ptr::NonNull; } -/// Macro to generate an implementation of [`Adapter`] for instrusive container and items. +/// Macro to generate an implementation of [`Adapter`] for intrusive container and items. /// /// The basic syntax to create an adapter is: /// diff --git a/foyer-memory/benches/bench_dynamic_dispatch.rs b/foyer-memory/benches/bench_dynamic_dispatch.rs index 1e92d5c9..144676b6 100644 --- a/foyer-memory/benches/bench_dynamic_dispatch.rs +++ b/foyer-memory/benches/bench_dynamic_dispatch.rs @@ -106,7 +106,7 @@ fn main() { for loops in [100_000, 1_000_000, 10_000_000] { println!(); - println!(" statis - {} loops : {:?}", loops, bench_static_dispatch(&t, loops)); + println!(" static - {} loops : {:?}", loops, bench_static_dispatch(&t, loops)); println!( "box dynamic - {} loops : {:?}", loops, diff --git a/foyer-memory/src/context.rs b/foyer-memory/src/context.rs index 09b8037f..eba7eff7 100644 --- a/foyer-memory/src/context.rs +++ b/foyer-memory/src/context.rs @@ -21,7 +21,7 @@ pub enum CacheContext { Default, /// Mark the entry as low-priority. /// - /// The behaviour differs from different eviction algorithm. + /// The behavior differs from different eviction algorithm. LowPriority, } diff --git a/foyer-memory/src/eviction/lfu.rs b/foyer-memory/src/eviction/lfu.rs index 3f6ea3db..f17aaade 100644 --- a/foyer-memory/src/eviction/lfu.rs +++ b/foyer-memory/src/eviction/lfu.rs @@ -144,7 +144,7 @@ unsafe impl Sync for LfuHandle where T: Send + Sync + 'static {} /// This implementation is inspired by [Caffeine](https://github.com/ben-manes/caffeine) under Apache License 2.0 /// -/// A newcoming and hot entry is kept in `window`. +/// A new and hot entry is kept in `window`. /// /// When `window` is full, entries from it will overflow to `probation`. /// @@ -152,7 +152,7 @@ unsafe impl Sync for LfuHandle where T: Send + Sync + 'static {} /// /// When `protected` is full, entries from it will overflow to `probation`. /// -/// When evicting, the entry with a lower frequency from `window` or `probtion` will be evicted first, then from +/// When evicting, the entry with a lower frequency from `window` or `probation` will be evicted first, then from /// `protected`. pub struct Lfu where diff --git a/foyer-memory/src/eviction/mod.rs b/foyer-memory/src/eviction/mod.rs index b74ff289..e8eaa5e9 100644 --- a/foyer-memory/src/eviction/mod.rs +++ b/foyer-memory/src/eviction/mod.rs @@ -56,14 +56,14 @@ pub trait Eviction: Send + Sync + 'static { /// The base handle associated to the `ptr` must be set NOT in cache. unsafe fn pop(&mut self) -> Option>; - /// Notify the eviciton container that the `ptr` is acquired by **AN** external user. + /// Notify the eviction container that the `ptr` is acquired by **AN** external user. /// /// # Safety /// /// The given `ptr` can be EITHER in the eviction container OR not in the eviction container. unsafe fn acquire(&mut self, ptr: NonNull); - /// Notify the eviciton container that the `ptr` is released by **ALL** external users. + /// Notify the eviction container that the `ptr` is released by **ALL** external users. /// /// # Safety /// diff --git a/foyer-memory/src/generic.rs b/foyer-memory/src/generic.rs index 9d42dc46..3da8bc94 100644 --- a/foyer-memory/src/generic.rs +++ b/foyer-memory/src/generic.rs @@ -320,7 +320,7 @@ where return None; } - strict_assert!(handle.base().is_inited()); + strict_assert!(handle.base().is_initialized()); strict_assert!(!handle.base().has_refs()); // If the entry is deposit (emplace by deposit & never read), remove it from indexer to skip reinsertion. diff --git a/foyer-memory/src/handle.rs b/foyer-memory/src/handle.rs index 5f4254ae..4cca7464 100644 --- a/foyer-memory/src/handle.rs +++ b/foyer-memory/src/handle.rs @@ -85,7 +85,7 @@ impl Default for BaseHandle { } impl BaseHandle { - /// Create a uninited handle. + /// Create a uninitialized handle. #[inline(always)] pub fn new() -> Self { Self { @@ -109,7 +109,7 @@ impl BaseHandle { self.flags = BaseHandleFlags::empty(); } - /// Take key and value from the handle and reset it to the uninited state. + /// Take key and value from the handle and reset it to the uninitialized state. #[inline(always)] pub fn take(&mut self) -> (T, C, usize) { strict_assert!(self.entry.is_some()); @@ -121,9 +121,9 @@ impl BaseHandle { } } - /// Return `true` if the handle is inited. + /// Return `true` if the handle is initialized. #[inline(always)] - pub fn is_inited(&self) -> bool { + pub fn is_initialized(&self) -> bool { self.entry.is_some() } @@ -131,7 +131,7 @@ impl BaseHandle { /// /// # Panics /// - /// Panics if the handle is uninited. + /// Panics if the handle is uninitialized. #[inline(always)] pub fn hash(&self) -> u64 { self.hash @@ -141,7 +141,7 @@ impl BaseHandle { /// /// # Panics /// - /// Panics if the handle is uninited. + /// Panics if the handle is uninitialized. #[inline(always)] pub fn data_unwrap_unchecked(&self) -> &T { strict_assert!(self.entry.is_some()); @@ -152,7 +152,7 @@ impl BaseHandle { /// /// # Panics /// - /// Panics if the handle is uninited. + /// Panics if the handle is uninitialized. #[inline(always)] pub fn context(&self) -> &C { strict_assert!(self.entry.is_some()); diff --git a/foyer-memory/src/lib.rs b/foyer-memory/src/lib.rs index 036ffb3f..f0cb72b6 100644 --- a/foyer-memory/src/lib.rs +++ b/foyer-memory/src/lib.rs @@ -18,7 +18,7 @@ //! //! There are a few goals to achieve with the crate: //! -//! 1. Pluggable eviction algorithm with the same abstraction. +//! 1. Plug-and-Play eviction algorithm with the same abstraction. //! 2. Tracking the real memory usage by the cache. Including both holding by the cache and by the external users. //! 3. Reduce the concurrent read-through requests into one. //! diff --git a/foyer-storage/src/compress.rs b/foyer-storage/src/compress.rs index 29f3448b..94cc3281 100644 --- a/foyer-storage/src/compress.rs +++ b/foyer-storage/src/compress.rs @@ -22,7 +22,7 @@ use crate::error::Error; /// The compression algorithm of the disk cache. #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, ValueEnum)] pub enum Compression { - /// No compression endabled. + /// No compression enabled. None, /// Use zstd compression. Zstd, @@ -31,7 +31,7 @@ pub enum Compression { } impl Compression { - /// Get the u8 that repersent the compression algorithm. + /// Get the u8 that represent the compression algorithm. pub fn to_u8(&self) -> u8 { match self { Self::None => 0, diff --git a/foyer-storage/src/device/bytes.rs b/foyer-storage/src/device/bytes.rs index 14dbfe91..6a53e83a 100644 --- a/foyer-storage/src/device/bytes.rs +++ b/foyer-storage/src/device/bytes.rs @@ -79,7 +79,7 @@ impl Clone for IoBuffer { } } -/// A 4K-aligend u8 vector. +/// A 4K-aligned u8 vector. /// /// # Growth /// diff --git a/foyer-storage/src/large/batch.rs b/foyer-storage/src/large/batch.rs index 459f6d9e..ed7e771d 100644 --- a/foyer-storage/src/large/batch.rs +++ b/foyer-storage/src/large/batch.rs @@ -333,7 +333,7 @@ pub struct InvalidStats { pub struct RegionHandle { /// Handle of the region to write. pub handle: GetCleanRegionHandle, - /// Offoset of the region to write. + /// Offset of the region to write. pub offset: u64, /// Length of the buffer to write. pub len: usize, diff --git a/foyer-storage/src/large/reclaimer.rs b/foyer-storage/src/large/reclaimer.rs index 92e7fddb..d32c765b 100644 --- a/foyer-storage/src/large/reclaimer.rs +++ b/foyer-storage/src/large/reclaimer.rs @@ -245,7 +245,7 @@ where // 1. Reclaim runner releases 1 permit on finish. (+1) // 2. There is a new clean region. (-1) // - // Because the total permits to modify is 0 and to avlid concurrent corner case, just forget the permit. + // Because the total permits to modify is 0 and to avoid concurrent corner case, just forget the permit. // // The permit only increase when the a clean region is taken to write. permit.forget(); diff --git a/foyer-storage/src/large/tombstone.rs b/foyer-storage/src/large/tombstone.rs index 45040539..b44a9a6d 100644 --- a/foyer-storage/src/large/tombstone.rs +++ b/foyer-storage/src/large/tombstone.rs @@ -38,7 +38,7 @@ use crate::{ pub struct TombstoneLogConfig { /// Path of the tombstone log. pub path: PathBuf, - /// If enabeld, `sync` will be called after writes to make sure the data is safely persisted on the device. + /// If enabled, `sync` will be called after writes to make sure the data is safely persisted on the device. pub flush: bool, } @@ -60,7 +60,7 @@ impl TombstoneLogConfigBuilder { /// Set whether to enable flush. /// - /// If enabeld, `sync` will be called after writes to make sure the data is safely persisted on the device. + /// If enabled, `sync` will be called after writes to make sure the data is safely persisted on the device. pub fn with_flush(mut self, flush: bool) -> Self { self.flush = flush; self diff --git a/foyer-storage/src/picker/utils.rs b/foyer-storage/src/picker/utils.rs index 5b3f5aee..a095ed36 100644 --- a/foyer-storage/src/picker/utils.rs +++ b/foyer-storage/src/picker/utils.rs @@ -211,7 +211,7 @@ where } } -/// A picker that pick region to eviciton with a FIFO behaviour. +/// A picker that pick region to eviction with a FIFO behavior. #[derive(Debug, Default)] pub struct FifoPicker { queue: VecDeque, diff --git a/foyer-storage/src/region.rs b/foyer-storage/src/region.rs index ee55ac3f..130bfa35 100644 --- a/foyer-storage/src/region.rs +++ b/foyer-storage/src/region.rs @@ -189,7 +189,7 @@ impl RegionManager { // Temporarily take pickers to make borrow checker happy. let mut pickers = std::mem::take(&mut eviction.eviction_pickers); - // Noitfy pickers. + // Notify pickers. for picker in pickers.iter_mut() { picker.on_region_evictable(&eviction.evictable, region); } @@ -225,7 +225,7 @@ impl RegionManager { } } - // If no region is selected, just ramdomly pick one. + // If no region is selected, just randomly pick one. let picked = picked.unwrap_or_else(|| { eviction .evictable @@ -239,7 +239,7 @@ impl RegionManager { eviction.evictable.remove(&picked).unwrap(); self.inner.metrics.storage_region_evictable.decrement(1); - // Noitfy pickers. + // Notify pickers. for picker in pickers.iter_mut() { picker.on_region_evict(&eviction.evictable, picked); } diff --git a/foyer-storage/src/store.rs b/foyer-storage/src/store.rs index 7fb658ea..5c9d804a 100644 --- a/foyer-storage/src/store.rs +++ b/foyer-storage/src/store.rs @@ -498,7 +498,7 @@ where /// The eviction pickers are applied in order. If the previous eviction picker doesn't pick any region, the next one /// will be applied. /// - /// If no eviction picker pickes a region, a region will be picked randomly. + /// If no eviction picker picks a region, a region will be picked randomly. /// /// Default: [ invalid ratio picker { threshold = 0.8 }, fifo picker ] pub fn with_eviction_pickers(mut self, eviction_pickers: Vec>) -> Self { @@ -623,7 +623,7 @@ where let write_runtime_handle = write_runtime_handle.clone(); let read_runtime_handle = read_runtime_handle.clone(); let user_runtime_handle = user_runtime_handle.clone(); - // Use the user runtiem to open engine. + // Use the user runtime to open engine. tokio::spawn(async move { match self.device_config { DeviceConfig::None => { diff --git a/foyer-storage/src/test_utils.rs b/foyer-storage/src/test_utils.rs index 26132575..317a85e7 100644 --- a/foyer-storage/src/test_utils.rs +++ b/foyer-storage/src/test_utils.rs @@ -55,7 +55,7 @@ where } impl BiasedPicker { - /// Create a biased picker with the geiven admit list. + /// Create a biased picker with the given admit list. pub fn new(admits: impl IntoIterator) -> Self where Q: Hash + Eq, @@ -100,9 +100,9 @@ pub enum Record { Evict(K), } -/// A recorder that records the cache entry admission and eviciton of a disk cache. +/// A recorder that records the cache entry admission and eviction of a disk cache. /// -/// [`Recorder`] should be used as both the admission picker and the reisnertion picker to record. +/// [`Recorder`] should be used as both the admission picker and the reinsertion picker to record. pub struct Recorder { records: Mutex>>, } diff --git a/foyer-util/Cargo.toml b/foyer-util/Cargo.toml index 7ded09ae..04cf81f0 100644 --- a/foyer-util/Cargo.toml +++ b/foyer-util/Cargo.toml @@ -13,8 +13,10 @@ publish = false [dependencies] bitmaps = "3" +bitvec = "1" bytes = "1" cfg-if = "1" +foyer-common = { path = "../foyer-common" } futures = "0.3" hashbrown = "0.14" itertools = { workspace = true } diff --git a/foyer-common/src/compact_bloom_filter.rs b/foyer-util/src/compact_bloom_filter.rs similarity index 97% rename from foyer-common/src/compact_bloom_filter.rs rename to foyer-util/src/compact_bloom_filter.rs index eea2957d..43c4c4f4 100644 --- a/foyer-common/src/compact_bloom_filter.rs +++ b/foyer-util/src/compact_bloom_filter.rs @@ -15,10 +15,9 @@ use std::{cell::UnsafeCell, sync::Arc}; use bitvec::prelude::*; +use foyer_common::strict_assert; use itertools::Itertools; -use crate::strict_assert; - /// Reduce two 64-bit hashes into one. /// /// Ported from CacheLib, which uses the `Hash128to64` function from Google's city hash. @@ -46,7 +45,8 @@ fn twang_mix64(val: u64) -> u64 { val } -/// [`CompactBloomFilter`] is composed of a series of contiguous bloom filters with each size is smaller than cacheline. +/// [`CompactBloomFilter`] is composed of a series of contiguous bloom filters with each size is smaller than cache +/// line. pub struct CompactBloomFilter { /// Bloom filter data. data: BitVec, @@ -113,7 +113,7 @@ impl CompactBloomFilter { self.data.fill(false); } - /// Create a new comapct bloom filter and return the shards. + /// Create a new compact bloom filter and return the shards. /// /// See [`CompactBloomFilterShard`]. pub fn shards(filters: usize, hashes: usize, bits: usize) -> Vec { diff --git a/foyer-util/src/lib.rs b/foyer-util/src/lib.rs index b7e5aa6c..85317159 100644 --- a/foyer-util/src/lib.rs +++ b/foyer-util/src/lib.rs @@ -13,6 +13,7 @@ // limitations under the License. pub mod batch; +pub mod compact_bloom_filter; pub mod continuum; pub mod erwlock; pub mod iostat; From 07bebcfe9ecb29aef1a13424822319f4a63a3b4f Mon Sep 17 00:00:00 2001 From: Croxx Date: Sat, 31 Aug 2024 19:40:14 +0800 Subject: [PATCH 15/40] chore: release foyer 0.11.1 (#681) Signed-off-by: MrCroxx --- CHANGELOG.md | 23 +++++++++++++++++++++++ foyer-bench/Cargo.toml | 4 ++-- foyer-common/Cargo.toml | 2 +- foyer-intrusive/Cargo.toml | 4 ++-- foyer-memory/Cargo.toml | 6 +++--- foyer-storage/Cargo.toml | 6 +++--- foyer/Cargo.toml | 8 ++++---- 7 files changed, 38 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 474e1dad..f217e5c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,26 @@ +## 2024-08-31 + +| crate | version | +| - | - | +| foyer | 0.11.1 | +| foyer-common | 0.9.1 | +| foyer-intrusive | 0.9.1 | +| foyer-memory | 0.7.1 | +| foyer-storage | 0.10.1 | +| foyer-bench | 0.3.1 | + +
+ +### Changes + +- Add metrics for serde. +- Refine `fetch` runtime usage. +- Fix unhandled low-layer errors. #674 #677 #679 +- Implement `Default` for `TokioRuntimeConfig`. +- Fix typos and format code with unstable features. + +
+ ## 2024-08-21 | crate | version | diff --git a/foyer-bench/Cargo.toml b/foyer-bench/Cargo.toml index 9036bd76..88e11c51 100644 --- a/foyer-bench/Cargo.toml +++ b/foyer-bench/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "foyer-bench" -version = "0.3.0" +version = "0.3.1" edition = "2021" authors = ["MrCroxx "] description = "bench tool for foyer - the hybrid cache for Rust" @@ -17,7 +17,7 @@ clap = { workspace = true } console-subscriber = { version = "0.4", optional = true } fastrace = { workspace = true, optional = true } fastrace-jaeger = { workspace = true, optional = true } -foyer = { version = "0.11.0", path = "../foyer" } +foyer = { version = "0.11.1", path = "../foyer" } futures = "0.3" hdrhistogram = "7" itertools = { workspace = true } diff --git a/foyer-common/Cargo.toml b/foyer-common/Cargo.toml index c4c8ae36..7d68cc0c 100644 --- a/foyer-common/Cargo.toml +++ b/foyer-common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "foyer-common" -version = "0.9.0" +version = "0.9.1" edition = "2021" authors = ["MrCroxx "] description = "common components for foyer - the hybrid cache for Rust" diff --git a/foyer-intrusive/Cargo.toml b/foyer-intrusive/Cargo.toml index cbcfc837..d2a980ef 100644 --- a/foyer-intrusive/Cargo.toml +++ b/foyer-intrusive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "foyer-intrusive" -version = "0.9.0" +version = "0.9.1" edition = "2021" authors = ["MrCroxx "] description = "intrusive data structures for foyer - the hybrid cache for Rust" @@ -11,7 +11,7 @@ readme = "../README.md" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -foyer-common = { version = "0.9.0", path = "../foyer-common" } +foyer-common = { version = "0.9.1", path = "../foyer-common" } itertools = { workspace = true } [features] diff --git a/foyer-memory/Cargo.toml b/foyer-memory/Cargo.toml index 7ed46d0e..975ce77b 100644 --- a/foyer-memory/Cargo.toml +++ b/foyer-memory/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "foyer-memory" -version = "0.7.0" +version = "0.7.1" edition = "2021" authors = ["MrCroxx "] description = "memory cache for foyer - the hybrid cache for Rust" @@ -15,8 +15,8 @@ ahash = "0.8" bitflags = "2" cmsketch = "0.2.1" fastrace = { workspace = true } -foyer-common = { version = "0.9.0", path = "../foyer-common" } -foyer-intrusive = { version = "0.9.0", path = "../foyer-intrusive" } +foyer-common = { version = "0.9.1", path = "../foyer-common" } +foyer-intrusive = { version = "0.9.1", path = "../foyer-intrusive" } futures = "0.3" hashbrown = "0.14" itertools = { workspace = true } diff --git a/foyer-storage/Cargo.toml b/foyer-storage/Cargo.toml index d633aa8a..5b130b3b 100644 --- a/foyer-storage/Cargo.toml +++ b/foyer-storage/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "foyer-storage" -version = "0.10.0" +version = "0.10.1" edition = "2021" authors = ["MrCroxx "] description = "storage engine for foyer - the hybrid cache for Rust" @@ -24,8 +24,8 @@ bytes = "1" clap = { workspace = true } either = "1" fastrace = { workspace = true } -foyer-common = { version = "0.9.0", path = "../foyer-common" } -foyer-memory = { version = "0.7.0", path = "../foyer-memory" } +foyer-common = { version = "0.9.1", path = "../foyer-common" } +foyer-memory = { version = "0.7.1", path = "../foyer-memory" } futures = "0.3" itertools = { workspace = true } lazy_static = "1" diff --git a/foyer/Cargo.toml b/foyer/Cargo.toml index 126b5692..b0854039 100644 --- a/foyer/Cargo.toml +++ b/foyer/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "foyer" -version = "0.11.0" +version = "0.11.1" edition = "2021" authors = ["MrCroxx "] description = "Hybrid cache for Rust" @@ -15,9 +15,9 @@ rust-version = "1.77" ahash = "0.8" anyhow = "1" fastrace = { workspace = true } -foyer-common = { version = "0.9.0", path = "../foyer-common" } -foyer-memory = { version = "0.7.0", path = "../foyer-memory" } -foyer-storage = { version = "0.10.0", path = "../foyer-storage" } +foyer-common = { version = "0.9.1", path = "../foyer-common" } +foyer-memory = { version = "0.7.1", path = "../foyer-memory" } +foyer-storage = { version = "0.10.1", path = "../foyer-storage" } futures = "0.3" pin-project = "1" tokio = { workspace = true } From 9581d99303782166600bad7f4c7e7d4cab08136f Mon Sep 17 00:00:00 2001 From: Arsh <47524932+spector-9@users.noreply.github.com> Date: Thu, 5 Sep 2024 13:14:28 +0530 Subject: [PATCH 16/40] fix: build on windows (#684) * Fix: Foyer-common for windows - use fs4 crate to get available space rather than using custom function to make it crossplatform. * Fix: foyer-storage for windows - Manually seek and read/write. Rather than using read_at and write_at. * Fix: foyer-util for windows - Scope unused function to unix * Fix: foyer storage test * Fix: Use read_at/write_at for unix * Fix: use seek_(read/write) from file_ext in windows * Fix: Replace result::Result with io::Result Co-authored-by: Croxx * Chore: cargo fmt * Fix: Spelling for privileged in docs * Fix: foyer storage test - Use write_all instead of write to handle amount of bytes written * Fix: Import statements * chore: try to setup ci on Windows Signed-off-by: MrCroxx * refactor: remove seek on windows Signed-off-by: MrCroxx * chore: remove nix dep Signed-off-by: MrCroxx * fix: remove cargo sort check on windows ci Signed-off-by: MrCroxx * fix: try fix windows ci with extra deps Signed-off-by: MrCroxx * fix: fix ci Signed-off-by: MrCroxx * chore: fix udeps ci Signed-off-by: MrCroxx * fix: fix udeps on windows Signed-off-by: MrCroxx --------- Signed-off-by: MrCroxx Co-authored-by: Croxx --- .github/template/template.yml | 24 +++++++++++++++----- .github/workflows/main.yml | 23 ++++++++++++++----- .github/workflows/pull-request.yml | 23 ++++++++++++++----- foyer-common/Cargo.toml | 2 +- foyer-common/src/fs.rs | 13 +++++------ foyer-common/src/lib.rs | 1 - foyer-memory/Cargo.toml | 1 - foyer-storage/src/device/direct_file.rs | 30 ++++++++++++++++++------- foyer-storage/src/device/direct_fs.rs | 28 +++++++++++++++++------ foyer-storage/src/large/generic.rs | 14 ++++++++++-- foyer-util/Cargo.toml | 6 +++-- foyer-util/src/iostat.rs | 7 +++++- 12 files changed, 126 insertions(+), 46 deletions(-) diff --git a/.github/template/template.yml b/.github/template/template.yml index 8d638b2c..ee8bd182 100644 --- a/.github/template/template.yml +++ b/.github/template/template.yml @@ -38,7 +38,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest] + os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - name: Checkout @@ -57,6 +57,12 @@ jobs: ~/.cargo/registry/cache/ ~/.cargo/git/db/ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }}-${{ env.CACHE_KEY_SUFFIX }}-rust-udeps + - name: Install NASM for aws-lc-rs on Windows + if: runner.os == 'Windows' + uses: ilammy/setup-nasm@v1 + - name: Install ninja-build tool for aws-lc-fips-sys on Windows + if: runner.os == 'Windows' + uses: seanmiddleditch/gha-setup-ninja@v5 - name: Install cargo-udeps if: steps.cache.outputs.cache-hit != 'true' run: | @@ -71,7 +77,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest] + os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - name: Checkout @@ -106,7 +112,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest] + os: [ubuntu-latest, macos-latest, windows-latest] rust_toolchain: [stable, 1.77] runs-on: ${{ matrix.os }} steps: @@ -131,7 +137,15 @@ jobs: if: steps.cache.outputs.cache-hit != 'true' run: | cargo install cargo-sort --locked + - name: Install NASM for aws-lc-rs on Windows + if: runner.os == 'Windows' + uses: ilammy/setup-nasm@v1 + - name: Install ninja-build tool for aws-lc-fips-sys on Windows + if: runner.os == 'Windows' + uses: seanmiddleditch/gha-setup-ninja@v5 - name: Run rust cargo-sort check + # https://github.com/DevinR528/cargo-sort/issues/56 + if: matrix.os != 'windows-latest' run: | cargo sort -w -c - name: Run rust format check @@ -171,7 +185,7 @@ jobs: cargo llvm-cov --no-report run --features "mtrace,jaeger" --example tail_based_tracing cargo llvm-cov --no-report run --features "mtrace,ot" --example tail_based_tracing - name: Run foyer-bench with coverage - if: matrix.os == 'ubuntu-latest' + if: runner.os == 'Linux' env: RUST_BACKTRACE: 1 CI: true @@ -182,7 +196,7 @@ jobs: run: | cargo llvm-cov report --lcov --output-path lcov.info - uses: codecov/codecov-action@v4 - if: matrix.os == 'ubuntu-latest' && matrix.rust_toolchain == 'stable' + if: runner.os == 'Linux' && matrix.rust_toolchain == 'stable' env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} with: diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0e57ce28..062b3542 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -45,7 +45,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest] + os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - name: Checkout @@ -64,6 +64,12 @@ jobs: ~/.cargo/registry/cache/ ~/.cargo/git/db/ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }}-${{ env.CACHE_KEY_SUFFIX }}-rust-udeps + - name: Install NASM for aws-lc-rs on Windows + if: runner.os == 'Windows' + uses: ilammy/setup-nasm@v1 + - name: Install ninja-build tool for aws-lc-fips-sys on Windows + if: runner.os == 'Windows' + uses: seanmiddleditch/gha-setup-ninja@v5 - name: Install cargo-udeps if: steps.cache.outputs.cache-hit != 'true' run: | @@ -78,7 +84,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest] + os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - name: Checkout @@ -113,7 +119,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest] + os: [ubuntu-latest, macos-latest, windows-latest] rust_toolchain: [stable, 1.77] runs-on: ${{ matrix.os }} steps: @@ -138,7 +144,14 @@ jobs: if: steps.cache.outputs.cache-hit != 'true' run: | cargo install cargo-sort --locked + - name: Install NASM for aws-lc-rs on Windows + if: runner.os == 'Windows' + uses: ilammy/setup-nasm@v1 + - name: Install ninja-build tool for aws-lc-fips-sys on Windows + if: runner.os == 'Windows' + uses: seanmiddleditch/gha-setup-ninja@v5 - name: Run rust cargo-sort check + if: matrix.os != 'windows-latest' run: | cargo sort -w -c - name: Run rust format check @@ -178,7 +191,7 @@ jobs: cargo llvm-cov --no-report run --features "mtrace,jaeger" --example tail_based_tracing cargo llvm-cov --no-report run --features "mtrace,ot" --example tail_based_tracing - name: Run foyer-bench with coverage - if: matrix.os == 'ubuntu-latest' + if: runner.os == 'Linux' env: RUST_BACKTRACE: 1 CI: true @@ -189,7 +202,7 @@ jobs: run: | cargo llvm-cov report --lcov --output-path lcov.info - uses: codecov/codecov-action@v4 - if: matrix.os == 'ubuntu-latest' && matrix.rust_toolchain == 'stable' + if: runner.os == 'Linux' && matrix.rust_toolchain == 'stable' env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} with: diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index fe48b0b3..e2bbd251 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -44,7 +44,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest] + os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - name: Checkout @@ -63,6 +63,12 @@ jobs: ~/.cargo/registry/cache/ ~/.cargo/git/db/ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }}-${{ env.CACHE_KEY_SUFFIX }}-rust-udeps + - name: Install NASM for aws-lc-rs on Windows + if: runner.os == 'Windows' + uses: ilammy/setup-nasm@v1 + - name: Install ninja-build tool for aws-lc-fips-sys on Windows + if: runner.os == 'Windows' + uses: seanmiddleditch/gha-setup-ninja@v5 - name: Install cargo-udeps if: steps.cache.outputs.cache-hit != 'true' run: | @@ -77,7 +83,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest] + os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - name: Checkout @@ -112,7 +118,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest] + os: [ubuntu-latest, macos-latest, windows-latest] rust_toolchain: [stable, 1.77] runs-on: ${{ matrix.os }} steps: @@ -137,7 +143,14 @@ jobs: if: steps.cache.outputs.cache-hit != 'true' run: | cargo install cargo-sort --locked + - name: Install NASM for aws-lc-rs on Windows + if: runner.os == 'Windows' + uses: ilammy/setup-nasm@v1 + - name: Install ninja-build tool for aws-lc-fips-sys on Windows + if: runner.os == 'Windows' + uses: seanmiddleditch/gha-setup-ninja@v5 - name: Run rust cargo-sort check + if: matrix.os != 'windows-latest' run: | cargo sort -w -c - name: Run rust format check @@ -177,7 +190,7 @@ jobs: cargo llvm-cov --no-report run --features "mtrace,jaeger" --example tail_based_tracing cargo llvm-cov --no-report run --features "mtrace,ot" --example tail_based_tracing - name: Run foyer-bench with coverage - if: matrix.os == 'ubuntu-latest' + if: runner.os == 'Linux' env: RUST_BACKTRACE: 1 CI: true @@ -188,7 +201,7 @@ jobs: run: | cargo llvm-cov report --lcov --output-path lcov.info - uses: codecov/codecov-action@v4 - if: matrix.os == 'ubuntu-latest' && matrix.rust_toolchain == 'stable' + if: runner.os == 'Linux' && matrix.rust_toolchain == 'stable' env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} with: diff --git a/foyer-common/Cargo.toml b/foyer-common/Cargo.toml index 7d68cc0c..41a07d11 100644 --- a/foyer-common/Cargo.toml +++ b/foyer-common/Cargo.toml @@ -15,11 +15,11 @@ bytes = "1" cfg-if = "1" crossbeam = "0.8" fastrace = { workspace = true } +fs4 = "0.9.1" futures = "0.3" hashbrown = "0.14" itertools = { workspace = true } metrics = { workspace = true } -nix = { version = "0.29", features = ["fs"] } parking_lot = { version = "0.12", features = ["arc_lock"] } pin-project = "1" serde = { workspace = true } diff --git a/foyer-common/src/fs.rs b/foyer-common/src/fs.rs index fdc42dbf..97a1c7c2 100644 --- a/foyer-common/src/fs.rs +++ b/foyer-common/src/fs.rs @@ -14,13 +14,10 @@ use std::path::Path; -use nix::{errno::Errno, sys::statvfs::statvfs}; - -/// Get the freespace of the device that contains the given path. -pub fn freespace(path: impl AsRef) -> Result { - let stat = statvfs(path.as_ref())?; - let res = stat.blocks_available() as usize * stat.fragment_size() as usize; - Ok(res) +/// Returns the available space. Available space in unix is space reserved for privileged user + +/// free space. +pub fn freespace(path: impl AsRef) -> std::io::Result { + fs4::free_space(path).map(|v| v as usize) } #[cfg(test)] @@ -57,7 +54,7 @@ mod tests { println!("{}", df); - assert_eq!(v1, v2); + assert_eq!(v1 as usize, v2); } } } diff --git a/foyer-common/src/lib.rs b/foyer-common/src/lib.rs index bf8f6884..4aeb6ccd 100644 --- a/foyer-common/src/lib.rs +++ b/foyer-common/src/lib.rs @@ -50,5 +50,4 @@ pub mod tracing; pub mod wait_group; /// File system utils. -#[cfg(any(target_os = "linux", target_os = "macos"))] pub mod fs; diff --git a/foyer-memory/Cargo.toml b/foyer-memory/Cargo.toml index 975ce77b..e2ea5a19 100644 --- a/foyer-memory/Cargo.toml +++ b/foyer-memory/Cargo.toml @@ -20,7 +20,6 @@ foyer-intrusive = { version = "0.9.1", path = "../foyer-intrusive" } futures = "0.3" hashbrown = "0.14" itertools = { workspace = true } -libc = "0.2" parking_lot = "0.12" pin-project = "1" serde = { workspace = true } diff --git a/foyer-storage/src/device/direct_file.rs b/foyer-storage/src/device/direct_file.rs index 7d2f8aa8..e44eb192 100644 --- a/foyer-storage/src/device/direct_file.rs +++ b/foyer-storage/src/device/direct_file.rs @@ -88,13 +88,20 @@ impl DirectFileDevice { ); let file = self.file.clone(); + asyncify_with_runtime(&self.runtime, move || { - #[cfg(target_family = "unix")] - use std::os::unix::fs::FileExt; #[cfg(target_family = "windows")] - use std::os::windows::fs::FileExt; + let written = { + use std::os::windows::fs::FileExt; + file.seek_write(buf.as_aligned(), offset)? + }; + + #[cfg(target_family = "unix")] + let written = { + use std::os::unix::fs::FileExt; + file.write_at(buf.as_aligned(), offset)? + }; - let written = file.write_at(buf.as_aligned(), offset)?; if written != aligned { return Err(anyhow::anyhow!("written {written}, expected: {aligned}").into()); } @@ -124,13 +131,20 @@ impl DirectFileDevice { } let file = self.file.clone(); + let mut buffer = asyncify_with_runtime(&self.runtime, move || { - #[cfg(target_family = "unix")] - use std::os::unix::fs::FileExt; #[cfg(target_family = "windows")] - use std::os::windows::fs::FileExt; + let read = { + use std::os::windows::fs::FileExt; + file.seek_read(buf.as_mut(), offset)? + }; + + #[cfg(target_family = "unix")] + let read = { + use std::os::unix::fs::FileExt; + file.read_at(buf.as_mut(), offset)? + }; - let read = file.read_at(buf.as_mut(), offset)?; if read != aligned { return Err(anyhow::anyhow!("read {read}, expected: {aligned}").into()); } diff --git a/foyer-storage/src/device/direct_fs.rs b/foyer-storage/src/device/direct_fs.rs index ed44947a..85fe4081 100644 --- a/foyer-storage/src/device/direct_fs.rs +++ b/foyer-storage/src/device/direct_fs.rs @@ -163,13 +163,20 @@ impl Dev for DirectFsDevice { ); let file = self.file(region).clone(); + asyncify_with_runtime(&self.inner.runtime, move || { - #[cfg(target_family = "unix")] - use std::os::unix::fs::FileExt; #[cfg(target_family = "windows")] - use std::os::windows::fs::FileExt; + let written = { + use std::os::windows::fs::FileExt; + file.seek_write(buf.as_aligned(), offset)? + }; + + #[cfg(target_family = "unix")] + let written = { + use std::os::unix::fs::FileExt; + file.write_at(buf.as_aligned(), offset)? + }; - let written = file.write_at(buf.as_aligned(), offset)?; if written != aligned { return Err(anyhow::anyhow!("written {written}, expected: {aligned}").into()); } @@ -198,13 +205,20 @@ impl Dev for DirectFsDevice { } let file = self.file(region).clone(); + let mut buffer = asyncify_with_runtime(&self.inner.runtime, move || { #[cfg(target_family = "unix")] - use std::os::unix::fs::FileExt; + let read = { + use std::os::unix::fs::FileExt; + file.read_at(buf.as_mut(), offset)? + }; + #[cfg(target_family = "windows")] - use std::os::windows::fs::FileExt; + let read = { + use std::os::windows::fs::FileExt; + file.seek_read(buf.as_mut(), offset)? + }; - let read = file.read_at(buf.as_mut(), offset)?; if read != aligned { return Err(anyhow::anyhow!("read {read}, expected: {aligned}").into()); } diff --git a/foyer-storage/src/large/generic.rs b/foyer-storage/src/large/generic.rs index f19fec4c..fd307d9a 100644 --- a/foyer-storage/src/large/generic.rs +++ b/foyer-storage/src/large/generic.rs @@ -494,7 +494,7 @@ where #[cfg(test)] mod tests { - use std::{fs::File, os::unix::fs::FileExt, path::Path}; + use std::{fs::File, path::Path}; use ahash::RandomState; use foyer_memory::{Cache, CacheBuilder, FifoConfig}; @@ -945,8 +945,18 @@ mod tests { if !entry.metadata().unwrap().is_file() { continue; } + let file = File::options().write(true).open(entry.path()).unwrap(); - file.write_all_at(&[b'x'; 4 * 1024], 0).unwrap(); + #[cfg(target_family = "unix")] + { + use std::os::unix::fs::FileExt; + file.write_all_at(&[b'x'; 4 * 1024], 0).unwrap(); + } + #[cfg(target_family = "windows")] + { + use std::os::windows::fs::FileExt; + file.seek_write(&[b'x'; 4 * 1024], 0).unwrap(); + } } assert!(store.load(memory.hash(&1)).await.unwrap().is_none()); diff --git a/foyer-util/Cargo.toml b/foyer-util/Cargo.toml index 04cf81f0..05374840 100644 --- a/foyer-util/Cargo.toml +++ b/foyer-util/Cargo.toml @@ -20,11 +20,13 @@ foyer-common = { path = "../foyer-common" } futures = "0.3" hashbrown = "0.14" itertools = { workspace = true } -libc = "0.2" -nix = { version = "0.29", features = ["fs"] } parking_lot = { version = "0.12", features = ["arc_lock"] } serde = { workspace = true } tokio = { workspace = true } +[target.'cfg(unix)'.dependencies] +libc = "0.2" +nix = { version = "0.29", features = ["fs"] } + [dev-dependencies] rand = "0.8.5" diff --git a/foyer-util/src/iostat.rs b/foyer-util/src/iostat.rs index cf703186..28857701 100644 --- a/foyer-util/src/iostat.rs +++ b/foyer-util/src/iostat.rs @@ -26,9 +26,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::path::{Path, PathBuf}; +use std::path::Path; +#[cfg(unix)] +use std::path::PathBuf; use itertools::Itertools; +#[cfg(unix)] use nix::{fcntl::readlink, sys::stat::stat}; // TODO(MrCroxx): use `expect` after `lint_reasons` is stable. @@ -64,6 +67,7 @@ pub fn detect_fs_type(path: impl AsRef) -> FsType { /// Given a normal file path, returns the containing block device static file path (of the /// partition). +#[cfg(unix)] pub fn file_stat_path(path: impl AsRef) -> PathBuf { let st_dev = stat(path.as_ref()).unwrap().st_dev; @@ -77,6 +81,7 @@ pub fn file_stat_path(path: impl AsRef) -> PathBuf { dev_stat_path(devname.to_str().unwrap()) } +#[cfg(unix)] pub fn dev_stat_path(devname: &str) -> PathBuf { let classpath = Path::new("/sys/class/block").join(devname); let devclass = readlink(&classpath).unwrap(); From de50258e21531848224a7827606fac25941e5fca Mon Sep 17 00:00:00 2001 From: Croxx Date: Thu, 5 Sep 2024 15:58:37 +0800 Subject: [PATCH 17/40] chore: move fs4 deps to foyer-storage (#685) Signed-off-by: MrCroxx --- foyer-common/Cargo.toml | 1 - foyer-common/src/fs.rs | 60 ------------------------- foyer-common/src/lib.rs | 3 -- foyer-storage/Cargo.toml | 1 + foyer-storage/src/device/direct_file.rs | 7 +-- foyer-storage/src/device/direct_fs.rs | 7 +-- 6 files changed, 9 insertions(+), 70 deletions(-) delete mode 100644 foyer-common/src/fs.rs diff --git a/foyer-common/Cargo.toml b/foyer-common/Cargo.toml index 41a07d11..982448ed 100644 --- a/foyer-common/Cargo.toml +++ b/foyer-common/Cargo.toml @@ -15,7 +15,6 @@ bytes = "1" cfg-if = "1" crossbeam = "0.8" fastrace = { workspace = true } -fs4 = "0.9.1" futures = "0.3" hashbrown = "0.14" itertools = { workspace = true } diff --git a/foyer-common/src/fs.rs b/foyer-common/src/fs.rs deleted file mode 100644 index 97a1c7c2..00000000 --- a/foyer-common/src/fs.rs +++ /dev/null @@ -1,60 +0,0 @@ -// 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::path::Path; - -/// Returns the available space. Available space in unix is space reserved for privileged user + -/// free space. -pub fn freespace(path: impl AsRef) -> std::io::Result { - fs4::free_space(path).map(|v| v as usize) -} - -#[cfg(test)] -mod tests { - use std::{ - env::{current_dir, var}, - process::Command, - }; - - use itertools::Itertools; - - use super::*; - - #[test] - #[ignore] - fn test() { - if var("CI").unwrap_or("".to_string()) != "true" { - let dir = current_dir().unwrap(); - let path = dir.as_os_str().to_str().unwrap(); - - println!("{}", path); - - let v1 = freespace(path).unwrap(); - let df = String::from_utf8(Command::new("df").args(["-P", path]).output().unwrap().stdout).unwrap(); - let bs: usize = df.trim().split('\n').next().unwrap().split_whitespace().collect_vec()[1] - .strip_suffix("-blocks") - .unwrap() - .parse() - .unwrap(); - let av: usize = df.trim().split('\n').last().unwrap().split_whitespace().collect_vec()[3] - .parse() - .unwrap(); - let v2 = bs * av; - - println!("{}", df); - - assert_eq!(v1 as usize, v2); - } - } -} diff --git a/foyer-common/src/lib.rs b/foyer-common/src/lib.rs index 4aeb6ccd..68479e8c 100644 --- a/foyer-common/src/lib.rs +++ b/foyer-common/src/lib.rs @@ -48,6 +48,3 @@ pub mod runtime; pub mod tracing; /// An async wait group implementation. pub mod wait_group; - -/// File system utils. -pub mod fs; diff --git a/foyer-storage/Cargo.toml b/foyer-storage/Cargo.toml index 5b130b3b..ff29e3a3 100644 --- a/foyer-storage/Cargo.toml +++ b/foyer-storage/Cargo.toml @@ -26,6 +26,7 @@ either = "1" fastrace = { workspace = true } foyer-common = { version = "0.9.1", path = "../foyer-common" } foyer-memory = { version = "0.7.1", path = "../foyer-memory" } +fs4 = "0.9.1" futures = "0.3" itertools = { workspace = true } lazy_static = "1" diff --git a/foyer-storage/src/device/direct_file.rs b/foyer-storage/src/device/direct_file.rs index e44eb192..b56cbd59 100644 --- a/foyer-storage/src/device/direct_file.rs +++ b/foyer-storage/src/device/direct_file.rs @@ -18,7 +18,8 @@ use std::{ sync::Arc, }; -use foyer_common::{asyncify::asyncify_with_runtime, bits, fs::freespace}; +use foyer_common::{asyncify::asyncify_with_runtime, bits}; +use fs4::free_space; use serde::{Deserialize, Serialize}; use tokio::runtime::Handle; @@ -301,10 +302,10 @@ impl DirectFileDeviceOptionsBuilder { let align_v = |value: usize, align: usize| value - value % align; let capacity = self.capacity.unwrap_or({ - // Create an empty directory before to get freespace. + // Create an empty directory before to get free space. let dir = path.parent().expect("path must point to a file").to_path_buf(); create_dir_all(&dir).unwrap(); - freespace(&dir).unwrap() / 10 * 8 + free_space(&dir).unwrap() as usize / 10 * 8 }); let capacity = align_v(capacity, ALIGN); diff --git a/foyer-storage/src/device/direct_fs.rs b/foyer-storage/src/device/direct_fs.rs index 85fe4081..307e8e7b 100644 --- a/foyer-storage/src/device/direct_fs.rs +++ b/foyer-storage/src/device/direct_fs.rs @@ -18,7 +18,8 @@ use std::{ sync::Arc, }; -use foyer_common::{asyncify::asyncify_with_runtime, bits, fs::freespace}; +use foyer_common::{asyncify::asyncify_with_runtime, bits}; +use fs4::free_space; use futures::future::try_join_all; use itertools::Itertools; use serde::{Deserialize, Serialize}; @@ -300,9 +301,9 @@ impl DirectFsDeviceOptionsBuilder { let align_v = |value: usize, align: usize| value - value % align; let capacity = self.capacity.unwrap_or({ - // Create an empty directory before to get freespace. + // Create an empty directory before to get free space. create_dir_all(&dir).unwrap(); - freespace(&dir).unwrap() / 10 * 8 + free_space(&dir).unwrap() as usize / 10 * 8 }); let capacity = align_v(capacity, ALIGN); From fec88f0fdf880b87c6f13bcfd9ac64af599f9757 Mon Sep 17 00:00:00 2001 From: Croxx Date: Fri, 6 Sep 2024 15:22:26 +0800 Subject: [PATCH 18/40] refactor: bump rust toolchain to 1.81.0 (#687) * refactor: replace allow with expect and warn allow usage Signed-off-by: MrCroxx * refactor: upgrade msrv to 1.81.0, remove trace feature for foyer-bench Signed-off-by: MrCroxx * fix: fix build Signed-off-by: MrCroxx * fix: fix check on non-linux Signed-off-by: MrCroxx --------- Signed-off-by: MrCroxx --- .github/template/template.yml | 4 +- .github/workflows/main.yml | 4 +- .github/workflows/pull-request.yml | 4 +- Makefile | 20 +++++----- README.md | 2 +- foyer-bench/Cargo.toml | 14 ------- foyer-bench/src/main.rs | 44 ++-------------------- foyer-common/src/code.rs | 2 - foyer-common/src/event.rs | 3 +- foyer-common/src/lib.rs | 1 + foyer-common/src/metrics.rs | 50 ++++++++++++++++++++++++- foyer-intrusive/src/lib.rs | 4 +- foyer-memory/src/eviction/s3fifo.rs | 5 +-- foyer-memory/src/eviction/test_utils.rs | 2 - foyer-memory/src/generic.rs | 22 +++-------- foyer-memory/src/lib.rs | 1 + foyer-storage/src/engine.rs | 8 +--- foyer-storage/src/large/flusher.rs | 3 +- foyer-storage/src/large/reclaimer.rs | 3 +- foyer-storage/src/large/recover.rs | 3 +- foyer-storage/src/large/scanner.rs | 6 +-- foyer-storage/src/lib.rs | 1 + foyer-storage/src/picker/mod.rs | 3 +- foyer-storage/src/region.rs | 6 +-- foyer-storage/src/serde.rs | 1 - foyer-storage/src/small/generic.rs | 8 +--- foyer-storage/src/storage/either.rs | 2 - foyer-storage/src/storage/mod.rs | 2 - foyer-storage/tests/storage_test.rs | 3 +- foyer-util/src/compact_bloom_filter.rs | 3 +- foyer-util/src/iostat.rs | 5 +-- foyer-util/src/lib.rs | 2 + foyer/Cargo.toml | 2 +- foyer/src/hybrid/cache.rs | 2 +- foyer/src/lib.rs | 1 + 35 files changed, 99 insertions(+), 147 deletions(-) diff --git a/.github/template/template.yml b/.github/template/template.yml index ee8bd182..f2fde5bb 100644 --- a/.github/template/template.yml +++ b/.github/template/template.yml @@ -3,7 +3,7 @@ name: on: env: - RUST_TOOLCHAIN_NIGHTLY: nightly-2024-03-17 + RUST_TOOLCHAIN_NIGHTLY: nightly-2024-07-19 CARGO_TERM_COLOR: always CACHE_KEY_SUFFIX: 20240821 @@ -113,7 +113,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] - rust_toolchain: [stable, 1.77] + rust_toolchain: [stable, 1.81.0] runs-on: ${{ matrix.os }} steps: - name: Checkout diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 062b3542..1c03e6d2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -11,7 +11,7 @@ on: branches: [main] workflow_dispatch: env: - RUST_TOOLCHAIN_NIGHTLY: nightly-2024-03-17 + RUST_TOOLCHAIN_NIGHTLY: nightly-2024-07-19 CARGO_TERM_COLOR: always CACHE_KEY_SUFFIX: 20240821 jobs: @@ -120,7 +120,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] - rust_toolchain: [stable, 1.77] + rust_toolchain: [stable, 1.81.0] runs-on: ${{ matrix.os }} steps: - name: Checkout diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index e2bbd251..cfe463a2 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -10,7 +10,7 @@ on: pull_request: branches: [main] env: - RUST_TOOLCHAIN_NIGHTLY: nightly-2024-03-17 + RUST_TOOLCHAIN_NIGHTLY: nightly-2024-07-19 CARGO_TERM_COLOR: always CACHE_KEY_SUFFIX: 20240821 jobs: @@ -119,7 +119,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] - rust_toolchain: [stable, 1.77] + rust_toolchain: [stable, 1.81.0] runs-on: ${{ matrix.os }} steps: - name: Checkout diff --git a/Makefile b/Makefile index a5545ef6..edb7c932 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,6 @@ check-all: cargo fmt --all cargo clippy --all-targets --features deadlock cargo clippy --all-targets --features tokio-console - cargo clippy --all-targets --features trace cargo clippy --all-targets --features sanity cargo clippy --all-targets --features mtrace cargo clippy --all-targets @@ -56,18 +55,17 @@ msrv: shellcheck ./scripts/* ./.github/template/generate.sh ./scripts/minimize-dashboards.sh - cargo +1.77 sort -w - cargo +1.77 fmt --all - cargo +1.77 clippy --all-targets --features deadlock - cargo +1.77 clippy --all-targets --features tokio-console - cargo +1.77 clippy --all-targets --features trace - cargo +1.77 clippy --all-targets - RUST_BACKTRACE=1 cargo +1.77 nextest run --all - RUST_BACKTRACE=1 cargo +1.77 test --doc - RUST_BACKTRACE=1 cargo +1.77 nextest run --run-ignored ignored-only --no-capture --workspace + cargo +1.81.0 sort -w + cargo +1.81.0 fmt --all + cargo +1.81.0 clippy --all-targets --features deadlock + cargo +1.81.0 clippy --all-targets --features tokio-console + cargo +1.81.0 clippy --all-targets + RUST_BACKTRACE=1 cargo +1.81.0 nextest run --all + RUST_BACKTRACE=1 cargo +1.81.0 test --doc + RUST_BACKTRACE=1 cargo +1.81.0 nextest run --run-ignored ignored-only --no-capture --workspace udeps: - RUSTFLAGS="--cfg tokio_unstable -Awarnings" cargo +nightly-2024-03-17 udeps --all-targets + RUSTFLAGS="--cfg tokio_unstable -Awarnings" cargo +nightly-2024-07-19 udeps --all-targets monitor: ./scripts/monitor.sh diff --git a/README.md b/README.md index 587f3872..69223b42 100644 --- a/README.md +++ b/README.md @@ -194,7 +194,7 @@ More examples and details can be found [here](https://github.com/foyer-rs/foyer/ ## Supported Rust Versions -*foyer* is built against the recent stable release. The minimum supported version is 1.77. The current *foyer* version is not guaranteed to build on Rust versions earlier than the minimum supported version. +*foyer* is built against the recent stable release. The minimum supported version is 1.81.0. The current *foyer* version is not guaranteed to build on Rust versions earlier than the minimum supported version. ## Development State & Roadmap diff --git a/foyer-bench/Cargo.toml b/foyer-bench/Cargo.toml index 88e11c51..0faff8a4 100644 --- a/foyer-bench/Cargo.toml +++ b/foyer-bench/Cargo.toml @@ -23,13 +23,6 @@ hdrhistogram = "7" itertools = { workspace = true } metrics = { workspace = true } metrics-exporter-prometheus = "0.15" -opentelemetry = { version = "0.24", optional = true } -opentelemetry-otlp = { version = "0.17", optional = true } -opentelemetry-semantic-conventions = { version = "0.16", optional = true } -opentelemetry_sdk = { version = "0.24", features = [ - "rt-tokio", - "trace", -], optional = true } parking_lot = "0.12" rand = "0.8.5" serde = { workspace = true } @@ -46,13 +39,6 @@ tikv-jemallocator = { version = "0.6", optional = true } [features] deadlock = ["parking_lot/deadlock_detection", "foyer/deadlock"] tokio-console = ["console-subscriber"] -trace = [ - "opentelemetry", - "opentelemetry_sdk", - "opentelemetry-otlp", - "tracing-opentelemetry", - "opentelemetry-semantic-conventions", -] strict_assertions = ["foyer/strict_assertions"] sanity = ["foyer/sanity"] jemalloc = ["tikv-jemallocator"] diff --git a/foyer-bench/src/main.rs b/foyer-bench/src/main.rs index 70f9f3af..98e69925 100644 --- a/foyer-bench/src/main.rs +++ b/foyer-bench/src/main.rs @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#![warn(clippy::allow_attributes)] + mod analyze; mod rate; mod text; @@ -337,46 +339,6 @@ fn setup() { console_subscriber::init(); } -#[cfg(feature = "trace")] -fn setup() { - use opentelemetry_sdk::{ - trace::{BatchConfigBuilder, Config}, - Resource, - }; - use opentelemetry_semantic_conventions::resource::SERVICE_NAME; - use tracing::Level; - use tracing_subscriber::{filter::Targets, prelude::*}; - - let tracing_config = Config::default().with_resource(Resource::new(vec![opentelemetry::KeyValue::new( - SERVICE_NAME, - "foyer-bench", - )])); - let batch_config = BatchConfigBuilder::default() - .with_max_queue_size(1048576) - .with_max_export_batch_size(4096) - .with_max_concurrent_exports(4) - .build(); - - let tracer = opentelemetry_otlp::new_pipeline() - .tracing() - .with_exporter(opentelemetry_otlp::new_exporter().tonic()) - .with_tracing_config(tracing_config) - .with_batch_config(batch_config) - .install_batch(opentelemetry_sdk::runtime::Tokio) - .unwrap(); - let opentelemetry_layer = tracing_opentelemetry::layer().with_tracer(tracer); - tracing_subscriber::registry() - .with( - Targets::new() - .with_target("foyer_storage", Level::DEBUG) - .with_target("foyer_common", Level::DEBUG) - .with_target("foyer_intrusive", Level::DEBUG) - .with_target("foyer_storage_bench", Level::DEBUG), - ) - .with(opentelemetry_layer) - .init(); -} - #[cfg(feature = "mtrace")] fn setup() { use fastrace::collector::Config; @@ -384,7 +346,7 @@ fn setup() { fastrace::set_reporter(reporter, Config::default().report_interval(Duration::from_millis(1))); } -#[cfg(not(any(feature = "tokio-console", feature = "trace", feature = "mtrace")))] +#[cfg(not(any(feature = "tokio-console", feature = "mtrace")))] fn setup() { use tracing_subscriber::{prelude::*, EnvFilter}; diff --git a/foyer-common/src/code.rs b/foyer-common/src/code.rs index 8e94ee65..ae4826e6 100644 --- a/foyer-common/src/code.rs +++ b/foyer-common/src/code.rs @@ -24,12 +24,10 @@ pub trait Value: Send + Sync + 'static {} impl Key for T {} impl Value for T {} -// TODO(MrCroxx): use `expect` after `lint_reasons` is stable. /// Key trait for the disk cache. pub trait StorageKey: Key + Serialize + DeserializeOwned {} impl StorageKey for T where T: Key + Serialize + DeserializeOwned {} -// TODO(MrCroxx): use `expect` after `lint_reasons` is stable. /// Value trait for the disk cache. pub trait StorageValue: Value + 'static + Serialize + DeserializeOwned {} impl StorageValue for T where T: Value + Serialize + DeserializeOwned {} diff --git a/foyer-common/src/event.rs b/foyer-common/src/event.rs index 9161ed9e..0c76edd9 100644 --- a/foyer-common/src/event.rs +++ b/foyer-common/src/event.rs @@ -22,9 +22,8 @@ pub trait EventListener: Send + Sync + 'static { /// Associated value type. type Value; - // TODO(MrCroxx): use `expect` after `lint_reasons` is stable. - #[allow(unused_variables)] /// Called when a cache entry is released from the in-memory cache. + #[expect(unused_variables)] fn on_memory_release(&self, key: Self::Key, value: Self::Value) where Self::Key: Key, diff --git a/foyer-common/src/lib.rs b/foyer-common/src/lib.rs index 68479e8c..208d9ee1 100644 --- a/foyer-common/src/lib.rs +++ b/foyer-common/src/lib.rs @@ -13,6 +13,7 @@ // limitations under the License. #![warn(missing_docs)] +#![warn(clippy::allow_attributes)] //! Shared components and utils for foyer. diff --git a/foyer-common/src/metrics.rs b/foyer-common/src/metrics.rs index f1f81132..0544551d 100644 --- a/foyer-common/src/metrics.rs +++ b/foyer-common/src/metrics.rs @@ -16,69 +16,115 @@ use std::fmt::Debug; use metrics::{counter, gauge, histogram, Counter, Gauge, Histogram}; -// TODO(MrCroxx): use `expect` after `lint_reasons` is stable. -#[allow(missing_docs)] +// FIXME: https://github.com/rust-lang/rust-analyzer/issues/17685 +// #[expect(missing_docs)] +/// ... ... #[derive(Clone)] pub struct Metrics { /* in-memory cache metrics */ + /// ... ... pub memory_insert: Counter, + /// ... ... pub memory_replace: Counter, + /// ... ... pub memory_hit: Counter, + /// ... ... pub memory_miss: Counter, + /// ... ... pub memory_remove: Counter, + /// ... ... pub memory_evict: Counter, + /// ... ... pub memory_reinsert: Counter, + /// ... ... pub memory_release: Counter, + /// ... ... pub memory_queue: Counter, + /// ... ... pub memory_fetch: Counter, + /// ... ... pub memory_usage: Gauge, /* disk cache metrics */ + /// ... ... pub storage_enqueue: Counter, + /// ... ... pub storage_hit: Counter, + /// ... ... pub storage_miss: Counter, + /// ... ... pub storage_delete: Counter, + /// ... ... pub storage_enqueue_duration: Histogram, + /// ... ... pub storage_hit_duration: Histogram, + /// ... ... pub storage_miss_duration: Histogram, + /// ... ... pub storage_delete_duration: Histogram, + /// ... ... pub storage_queue_rotate: Counter, + /// ... ... pub storage_queue_rotate_duration: Histogram, + /// ... ... pub storage_queue_drop: Counter, + /// ... ... pub storage_disk_write: Counter, + /// ... ... pub storage_disk_read: Counter, + /// ... ... pub storage_disk_flush: Counter, + /// ... ... pub storage_disk_write_bytes: Counter, + /// ... ... pub storage_disk_read_bytes: Counter, + /// ... ... pub storage_disk_write_duration: Histogram, + /// ... ... pub storage_disk_read_duration: Histogram, + /// ... ... pub storage_disk_flush_duration: Histogram, + /// ... ... pub storage_region_total: Gauge, + /// ... ... pub storage_region_clean: Gauge, + /// ... ... pub storage_region_evictable: Gauge, + /// ... ... pub storage_region_size_bytes: Gauge, + /// ... ... pub storage_entry_serialize_duration: Histogram, + /// ... ... pub storage_entry_deserialize_duration: Histogram, /* hybrid cache metrics */ + /// ... ... pub hybrid_insert: Counter, + /// ... ... pub hybrid_hit: Counter, + /// ... ... pub hybrid_miss: Counter, + /// ... ... pub hybrid_remove: Counter, + /// ... ... pub hybrid_insert_duration: Histogram, + /// ... ... pub hybrid_hit_duration: Histogram, + /// ... ... pub hybrid_miss_duration: Histogram, + /// ... ... pub hybrid_remove_duration: Histogram, + /// ... ... pub hybrid_fetch_duration: Histogram, } diff --git a/foyer-intrusive/src/lib.rs b/foyer-intrusive/src/lib.rs index aa44c7f2..bf64ea7f 100644 --- a/foyer-intrusive/src/lib.rs +++ b/foyer-intrusive/src/lib.rs @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -// TODO(MrCroxx): use `expect` after `lint_reasons` is stable. -#![allow(clippy::new_without_default)] +#![expect(clippy::new_without_default)] #![warn(missing_docs)] +#![warn(clippy::allow_attributes)] //! Intrusive data structures and utils for foyer. diff --git a/foyer-memory/src/eviction/s3fifo.rs b/foyer-memory/src/eviction/s3fifo.rs index e3aca1b9..1ae5d601 100644 --- a/foyer-memory/src/eviction/s3fifo.rs +++ b/foyer-memory/src/eviction/s3fifo.rs @@ -175,8 +175,7 @@ where self.evict_small_force() } - // TODO(MrCroxx): FIX ME!!! clippy false positive - #[allow(clippy::never_loop)] + #[expect(clippy::never_loop)] unsafe fn evict_small_force(&mut self) -> Option>> { while let Some(mut ptr) = self.small_queue.pop_front() { let handle = ptr.as_mut(); @@ -267,8 +266,6 @@ where handle.base_mut().set_in_eviction(true); } - // TODO: FIX ME! clippy false positive - // #[allow(clippy::never_loop)] unsafe fn pop(&mut self) -> Option> { if let Some(mut ptr) = self.evict() { let handle = ptr.as_mut(); diff --git a/foyer-memory/src/eviction/test_utils.rs b/foyer-memory/src/eviction/test_utils.rs index c83fd339..dd3f1f6f 100644 --- a/foyer-memory/src/eviction/test_utils.rs +++ b/foyer-memory/src/eviction/test_utils.rs @@ -15,8 +15,6 @@ use super::Eviction; use crate::handle::Handle; -// TODO(MrCroxx): use `expect` after `lint_reasons` is stable. -#[allow(clippy::type_complexity)] pub trait TestEviction: Eviction where Self::Handle: Handle, diff --git a/foyer-memory/src/generic.rs b/foyer-memory/src/generic.rs index 3da8bc94..8f20b089 100644 --- a/foyer-memory/src/generic.rs +++ b/foyer-memory/src/generic.rs @@ -64,8 +64,7 @@ struct SharedState { event_listener: Option>>, } -// TODO(MrCroxx): use `expect` after `lint_reasons` is stable. -#[allow(clippy::type_complexity)] +#[expect(clippy::type_complexity)] struct GenericCacheShard where K: Key, @@ -115,9 +114,8 @@ where } /// Insert a new entry into the cache. The handle for the new entry is returned. - // TODO(MrCroxx): use `expect` after `lint_reasons` is stable. - #[allow(clippy::type_complexity)] - #[allow(clippy::too_many_arguments)] + + #[expect(clippy::too_many_arguments)] #[fastrace::trace(name = "foyer::memory::generic::shard::emplace")] unsafe fn emplace( &mut self, @@ -241,8 +239,6 @@ where } /// Clear all cache entries. - // TODO(MrCroxx): use `expect` after `lint_reasons` is stable. - #[allow(clippy::type_complexity)] unsafe fn clear(&mut self, to_release: &mut Vec<(K, V, ::Context, usize)>) { // TODO(MrCroxx): Avoid collecting here? let ptrs = self.indexer.drain().collect_vec(); @@ -269,8 +265,6 @@ where } } - // TODO(MrCroxx): use `expect` after `lint_reasons` is stable. - #[allow(clippy::type_complexity)] #[fastrace::trace(name = "foyer::memory::generic::shard::evict")] unsafe fn evict(&mut self, weight: usize, to_release: &mut Vec<(K, V, ::Context, usize)>) { // TODO(MrCroxx): Use `let_chains` here after it is stable. @@ -292,8 +286,6 @@ where /// Release a handle used by an external user. /// /// Return `Some(..)` if the handle is released, or `None` if the handle is still in use. - // TODO(MrCroxx): use `expect` after `lint_reasons` is stable. - #[allow(clippy::type_complexity)] unsafe fn try_release_external_handle( &mut self, mut ptr: NonNull, @@ -307,8 +299,6 @@ where /// Return the entry if the handle is released. /// /// Recycle it if possible. - // TODO(MrCroxx): use `expect` after `lint_reasons` is stable. - #[allow(clippy::type_complexity)] unsafe fn try_release_handle( &mut self, mut ptr: NonNull, @@ -473,8 +463,7 @@ where } } -// TODO(MrCroxx): use `expect` after `lint_reasons` is stable. -#[allow(clippy::type_complexity)] +#[expect(clippy::type_complexity)] pub struct GenericCache where K: Key, @@ -1015,8 +1004,7 @@ mod tests { is_send_sync_static::>(); } - // TODO(MrCroxx): use `expect` after `lint_reasons` is stable. - #[allow(clippy::type_complexity)] + #[expect(clippy::type_complexity)] fn fuzzy(cache: Arc>>>) where E: Eviction, diff --git a/foyer-memory/src/lib.rs b/foyer-memory/src/lib.rs index f0cb72b6..cf3e2fe3 100644 --- a/foyer-memory/src/lib.rs +++ b/foyer-memory/src/lib.rs @@ -63,6 +63,7 @@ //! destroyed. #![warn(missing_docs)] +#![warn(clippy::allow_attributes)] mod cache; mod context; diff --git a/foyer-storage/src/engine.rs b/foyer-storage/src/engine.rs index d8d66b86..51357acd 100644 --- a/foyer-storage/src/engine.rs +++ b/foyer-storage/src/engine.rs @@ -101,8 +101,6 @@ enum StoreFuture { } impl StoreFuture { - // TODO(MrCroxx): use `expect` after `lint_reasons` is stable. - #[allow(clippy::type_complexity)] pub fn as_pin_mut(self: Pin<&mut Self>) -> StoreFuture, Pin<&mut F2>, Pin<&mut F3>, Pin<&mut F4>> { unsafe { match *Pin::get_unchecked_mut(self) { @@ -134,8 +132,7 @@ where } } -// TODO(MrCroxx): use `expect` after `lint_reasons` is stable. -#[allow(clippy::type_complexity)] +#[expect(clippy::type_complexity)] pub enum EngineConfig where K: StorageKey, @@ -164,8 +161,7 @@ where } } -// TODO(MrCroxx): use `expect` after `lint_reasons` is stable. -#[allow(clippy::type_complexity)] +#[expect(clippy::type_complexity)] pub enum Engine where K: StorageKey, diff --git a/foyer-storage/src/large/flusher.rs b/foyer-storage/src/large/flusher.rs index af523dfe..4572bc14 100644 --- a/foyer-storage/src/large/flusher.rs +++ b/foyer-storage/src/large/flusher.rs @@ -104,8 +104,7 @@ where V: StorageValue, S: HashBuilder + Debug, { - // TODO(MrCroxx): use `expect` after `lint_reasons` is stable. - #[allow(clippy::too_many_arguments)] + #[expect(clippy::too_many_arguments)] pub async fn open( config: &GenericLargeStorageConfig, indexer: Indexer, diff --git a/foyer-storage/src/large/reclaimer.rs b/foyer-storage/src/large/reclaimer.rs index d32c765b..b7a6b249 100644 --- a/foyer-storage/src/large/reclaimer.rs +++ b/foyer-storage/src/large/reclaimer.rs @@ -46,8 +46,7 @@ pub struct Reclaimer { } impl Reclaimer { - // TODO(MrCroxx): use `expect` after `lint_reasons` is stable. - #[allow(clippy::too_many_arguments)] + #[expect(clippy::too_many_arguments)] pub async fn open( region_manager: RegionManager, reclaim_semaphore: Arc, diff --git a/foyer-storage/src/large/recover.rs b/foyer-storage/src/large/recover.rs index d5f0ac1b..74ed3bcb 100644 --- a/foyer-storage/src/large/recover.rs +++ b/foyer-storage/src/large/recover.rs @@ -63,8 +63,7 @@ pub enum RecoverMode { pub struct RecoverRunner; impl RecoverRunner { - // TODO(MrCroxx): use `expect` after `lint_reasons` is stable. - #[allow(clippy::too_many_arguments)] + #[expect(clippy::too_many_arguments)] pub async fn run( config: &GenericLargeStorageConfig, regions: Range, diff --git a/foyer-storage/src/large/scanner.rs b/foyer-storage/src/large/scanner.rs index f735f26c..ce5eeb08 100644 --- a/foyer-storage/src/large/scanner.rs +++ b/foyer-storage/src/large/scanner.rs @@ -183,8 +183,7 @@ impl RegionScanner { Ok(Some((info, key))) } - // TODO(MrCroxx): use `expect` after `lint_reasons` is stable. - #[allow(dead_code)] + #[expect(dead_code)] pub async fn next_value(&mut self) -> Result> where V: StorageValue, @@ -207,8 +206,7 @@ impl RegionScanner { Ok(Some((info, value))) } - // TODO(MrCroxx): use `expect` after `lint_reasons` is stable. - #[allow(dead_code)] + #[expect(dead_code)] pub async fn next_kv(&mut self) -> Result> where K: StorageKey, diff --git a/foyer-storage/src/lib.rs b/foyer-storage/src/lib.rs index b30d05c3..14d081e7 100644 --- a/foyer-storage/src/lib.rs +++ b/foyer-storage/src/lib.rs @@ -16,6 +16,7 @@ #![cfg_attr(feature = "nightly", feature(allocator_api))] #![warn(missing_docs)] +#![warn(clippy::allow_attributes)] mod compress; mod device; diff --git a/foyer-storage/src/picker/mod.rs b/foyer-storage/src/picker/mod.rs index 98ff6f43..8cec22df 100644 --- a/foyer-storage/src/picker/mod.rs +++ b/foyer-storage/src/picker/mod.rs @@ -37,8 +37,7 @@ pub trait ReinsertionPicker: Send + Sync + 'static + Debug { /// The eviction picker for the disk cache. pub trait EvictionPicker: Send + Sync + 'static + Debug { /// Init the eviction picker with information. - // TODO(MrCroxx): use `expect` after `lint_reasons` is stable. - #[allow(unused_variables)] + #[expect(unused_variables)] fn init(&mut self, regions: usize, region_size: usize) {} /// Pick a region to evict. diff --git a/foyer-storage/src/region.rs b/foyer-storage/src/region.rs index 130bfa35..6046bab6 100644 --- a/foyer-storage/src/region.rs +++ b/foyer-storage/src/region.rs @@ -288,14 +288,12 @@ impl RegionManager { self.inner.regions.len() } - // TODO(MrCroxx): use `expect` after `lint_reasons` is stable. - #[allow(dead_code)] + #[expect(dead_code)] pub fn evictable_regions(&self) -> usize { self.inner.eviction.lock().evictable.len() } - // TODO(MrCroxx): use `expect` after `lint_reasons` is stable. - #[allow(dead_code)] + #[expect(dead_code)] pub fn clean_regions(&self) -> usize { self.inner.clean_region_rx.len() } diff --git a/foyer-storage/src/serde.rs b/foyer-storage/src/serde.rs index fcc805cb..89642226 100644 --- a/foyer-storage/src/serde.rs +++ b/foyer-storage/src/serde.rs @@ -47,7 +47,6 @@ pub struct KvInfo { pub struct EntrySerializer; impl EntrySerializer { - #[allow(clippy::needless_borrows_for_generic_args)] #[fastrace::trace(name = "foyer::storage::serde::serialize")] pub fn serialize<'a, K, V>( key: &'a K, diff --git a/foyer-storage/src/small/generic.rs b/foyer-storage/src/small/generic.rs index d7e6a983..cd086bc1 100644 --- a/foyer-storage/src/small/generic.rs +++ b/foyer-storage/src/small/generic.rs @@ -94,9 +94,7 @@ where todo!() } - // FIXME: REMOVE THE CLIPPY IGNORE. - // TODO(MrCroxx): use `expect` after `lint_reasons` is stable. - #[allow(clippy::manual_async_fn)] + #[expect(clippy::manual_async_fn)] fn load(&self, _hash: u64) -> impl Future>> + Send + 'static { async { todo!() } } @@ -115,9 +113,7 @@ where todo!() } - // TODO(MrCroxx): Remove the attr after impl. - // TODO(MrCroxx): use `expect` after `lint_reasons` is stable. - #[allow(clippy::manual_async_fn)] + #[expect(clippy::manual_async_fn)] fn wait(&self) -> impl Future + Send + 'static { async { todo!() } } diff --git a/foyer-storage/src/storage/either.rs b/foyer-storage/src/storage/either.rs index cdc64417..8708f453 100644 --- a/foyer-storage/src/storage/either.rs +++ b/foyer-storage/src/storage/either.rs @@ -35,8 +35,6 @@ enum OrderFuture { } impl OrderFuture { - // TODO(MrCroxx): use `expect` after `lint_reasons` is stable. - #[allow(clippy::type_complexity)] pub fn as_pin_mut(self: Pin<&mut Self>) -> OrderFuture, Pin<&mut F2>, Pin<&mut F3>> { unsafe { match *Pin::get_unchecked_mut(self) { diff --git a/foyer-storage/src/storage/mod.rs b/foyer-storage/src/storage/mod.rs index bbaba9a4..f3f56f49 100644 --- a/foyer-storage/src/storage/mod.rs +++ b/foyer-storage/src/storage/mod.rs @@ -23,8 +23,6 @@ use foyer_memory::CacheEntry; use crate::{device::monitor::DeviceStats, error::Result, serde::KvInfo, IoBytes}; /// The storage trait for the disk cache storage engine. -// TODO(MrCroxx): Remove this after in-memory cache event listener is removed. -#[allow(clippy::type_complexity)] pub trait Storage: Send + Sync + 'static + Clone + Debug { /// Disk cache key type. type Key: StorageKey; diff --git a/foyer-storage/tests/storage_test.rs b/foyer-storage/tests/storage_test.rs index a0a44fd3..e7983577 100644 --- a/foyer-storage/tests/storage_test.rs +++ b/foyer-storage/tests/storage_test.rs @@ -12,8 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// TODO(MrCroxx): use `expect` after `lint_reasons` is stable. -#![allow(clippy::identity_op)] +#![expect(clippy::identity_op)] use std::{path::Path, sync::Arc, time::Duration}; diff --git a/foyer-util/src/compact_bloom_filter.rs b/foyer-util/src/compact_bloom_filter.rs index 43c4c4f4..103244f5 100644 --- a/foyer-util/src/compact_bloom_filter.rs +++ b/foyer-util/src/compact_bloom_filter.rs @@ -117,8 +117,7 @@ impl CompactBloomFilter { /// /// See [`CompactBloomFilterShard`]. pub fn shards(filters: usize, hashes: usize, bits: usize) -> Vec { - // TODO(MrCroxx): use `expect` after `lint_reasons` is stable. - #[allow(clippy::arc_with_non_send_sync)] + #[expect(clippy::arc_with_non_send_sync)] let filter = Arc::new(UnsafeCell::new(Self::new(filters, hashes, bits))); (0..filters) .map(|idx| CompactBloomFilterShard { diff --git a/foyer-util/src/iostat.rs b/foyer-util/src/iostat.rs index 28857701..cc88e8e1 100644 --- a/foyer-util/src/iostat.rs +++ b/foyer-util/src/iostat.rs @@ -34,8 +34,6 @@ use itertools::Itertools; #[cfg(unix)] use nix::{fcntl::readlink, sys::stat::stat}; -// TODO(MrCroxx): use `expect` after `lint_reasons` is stable. -#[cfg_attr(not(target_os = "linux"), allow(dead_code))] #[derive(PartialEq, Clone, Copy, Debug)] pub enum FsType { Xfs, @@ -45,8 +43,7 @@ pub enum FsType { Others, } -// TODO(MrCroxx): use `expect` after `lint_reasons` is stable. -#[cfg_attr(not(target_os = "linux"), allow(unused_variables))] +#[cfg_attr(not(target_os = "linux"), expect(unused_variables))] pub fn detect_fs_type(path: impl AsRef) -> FsType { #[cfg(target_os = "linux")] { diff --git a/foyer-util/src/lib.rs b/foyer-util/src/lib.rs index 85317159..05d4f02d 100644 --- a/foyer-util/src/lib.rs +++ b/foyer-util/src/lib.rs @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#![warn(clippy::allow_attributes)] + pub mod batch; pub mod compact_bloom_filter; pub mod continuum; diff --git a/foyer/Cargo.toml b/foyer/Cargo.toml index b0854039..fecd526a 100644 --- a/foyer/Cargo.toml +++ b/foyer/Cargo.toml @@ -8,7 +8,7 @@ license = "Apache-2.0" repository = "https://github.com/foyer-rs/foyer" homepage = "https://github.com/foyer-rs/foyer" readme = "../README.md" -rust-version = "1.77" +rust-version = "1.81.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] diff --git a/foyer/src/hybrid/cache.rs b/foyer/src/hybrid/cache.rs index e132d982..9baf52c1 100644 --- a/foyer/src/hybrid/cache.rs +++ b/foyer/src/hybrid/cache.rs @@ -211,7 +211,7 @@ where pub async fn get(&self, key: &Q) -> anyhow::Result>> where K: Borrow, - Q: Hash + Eq + ?Sized + Send + Sync + 'static + Clone, + Q: Hash + Eq + Send + Sync + 'static + Clone, { root_span!(self, mut span, "foyer::hybrid::cache::get"); diff --git a/foyer/src/lib.rs b/foyer/src/lib.rs index 56085d53..dc0710cd 100644 --- a/foyer/src/lib.rs +++ b/foyer/src/lib.rs @@ -14,6 +14,7 @@ #![cfg_attr(feature = "nightly", feature(allocator_api))] #![warn(missing_docs)] +#![warn(clippy::allow_attributes)] //! A hybrid cache library that supports plug-and-play cache algorithms, in-memory cache and disk cache. From 4d9be75dd526edae99763b910b62941d9f0cfbef Mon Sep 17 00:00:00 2001 From: Croxx Date: Mon, 9 Sep 2024 13:41:08 +0800 Subject: [PATCH 19/40] feat: introduce foyer-cli framework (#693) Signed-off-by: MrCroxx --- Cargo.toml | 1 + codecov.yml | 3 +- foyer-cli/Cargo.toml | 23 +++++++++++++ foyer-cli/src/args/error.rs | 32 ++++++++++++++++++ foyer-cli/src/args/fio.rs | 67 +++++++++++++++++++++++++++++++++++++ foyer-cli/src/args/mod.rs | 48 ++++++++++++++++++++++++++ foyer-cli/src/main.rs | 41 +++++++++++++++++++++++ 7 files changed, 214 insertions(+), 1 deletion(-) create mode 100644 foyer-cli/Cargo.toml create mode 100644 foyer-cli/src/args/error.rs create mode 100644 foyer-cli/src/args/fio.rs create mode 100644 foyer-cli/src/args/mod.rs create mode 100644 foyer-cli/src/main.rs diff --git a/Cargo.toml b/Cargo.toml index ad2c6dcc..5e705eae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ members = [ "examples", "foyer", "foyer-bench", + "foyer-cli", "foyer-common", "foyer-intrusive", "foyer-memory", diff --git a/codecov.yml b/codecov.yml index 7863ed78..909bbf9d 100644 --- a/codecov.yml +++ b/codecov.yml @@ -21,4 +21,5 @@ coverage: informational: true only_pulls: true ignore: - - "foyer-util" \ No newline at end of file + - "foyer-util" + - "foyer-cli" \ No newline at end of file diff --git a/foyer-cli/Cargo.toml b/foyer-cli/Cargo.toml new file mode 100644 index 00000000..8d89b788 --- /dev/null +++ b/foyer-cli/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "foyer-cli" +version = "0.0.0" +edition = "2021" +authors = ["MrCroxx "] +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" diff --git a/foyer-cli/src/args/error.rs b/foyer-cli/src/args/error.rs new file mode 100644 index 00000000..4bd96da4 --- /dev/null +++ b/foyer-cli/src/args/error.rs @@ -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 = core::result::Result; diff --git a/foyer-cli/src/args/fio.rs b/foyer-cli/src/args/fio.rs new file mode 100644 index 00000000..5a087bdd --- /dev/null +++ b/foyer-cli/src/args/fio.rs @@ -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, +} + +impl Fio { + pub fn init() -> Result { + 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 { + &self.io_engines + } + + fn list_io_engines() -> Result> { + 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) + } +} diff --git a/foyer-cli/src/args/mod.rs b/foyer-cli/src/args/mod.rs new file mode 100644 index 00000000..5c5e4dd1 --- /dev/null +++ b/foyer-cli/src/args/mod.rs @@ -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, + + /// Directory for disk cache data. Use `DirectFs` as device. + /// + /// Either `file` or `dir` must be set. + #[arg(short, long)] + dir: Option, + + /// Size of the disk cache occupies. + #[arg(short, long)] + size: Option, +} + +pub fn run(args: ArgsArgs) { + println!("{args:#?}"); + + let fio = Fio::init().unwrap(); + + println!("{:#?}", fio.io_engines()); +} diff --git a/foyer-cli/src/main.rs b/foyer-cli/src/main.rs new file mode 100644 index 00000000..da1dee74 --- /dev/null +++ b/foyer-cli/src/main.rs @@ -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), + } +} From 260ef1429a658fe8467530f3cd5d7cbae61cd5ee Mon Sep 17 00:00:00 2001 From: Croxx Date: Mon, 9 Sep 2024 16:55:26 +0800 Subject: [PATCH 20/40] perf: introduce size hint for storage key and value (#695) --- foyer-common/src/code.rs | 18 ++++++++++++++---- foyer-storage/src/serde.rs | 11 +++++++++++ foyer-storage/src/store.rs | 3 ++- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/foyer-common/src/code.rs b/foyer-common/src/code.rs index ae4826e6..fb47b794 100644 --- a/foyer-common/src/code.rs +++ b/foyer-common/src/code.rs @@ -25,13 +25,23 @@ impl Key for T {} impl Value for T {} /// Key trait for the disk cache. -pub trait StorageKey: Key + Serialize + DeserializeOwned {} -impl StorageKey for T where T: Key + Serialize + DeserializeOwned {} +pub trait StorageKey: Key + Serialize + DeserializeOwned + Hint {} +impl StorageKey for T where T: Key + Serialize + DeserializeOwned + Hint {} /// Value trait for the disk cache. -pub trait StorageValue: Value + 'static + Serialize + DeserializeOwned {} -impl StorageValue for T where T: Value + Serialize + DeserializeOwned {} +pub trait StorageValue: Value + 'static + Serialize + DeserializeOwned + Hint {} +impl StorageValue for T where T: Value + Serialize + DeserializeOwned + Hint {} /// Hash builder trait. pub trait HashBuilder: BuildHasher + Send + Sync + 'static {} impl HashBuilder for T where T: BuildHasher + Send + Sync + 'static {} + +/// Hint functions collection. +pub trait Hint { + /// Size hint for serialization. + fn serialized_size_hint(&self) -> usize { + 0 + } +} + +impl Hint for T {} diff --git a/foyer-storage/src/serde.rs b/foyer-storage/src/serde.rs index 89642226..93a87f38 100644 --- a/foyer-storage/src/serde.rs +++ b/foyer-storage/src/serde.rs @@ -94,6 +94,17 @@ impl EntrySerializer { Ok(KvInfo { key_len, value_len }) } + + pub fn size_hint<'a, K, V>(key: &'a K, value: &'a V, compression: &'a Compression) -> usize + where + K: StorageKey, + V: StorageValue, + { + match compression { + Compression::Zstd | Compression::Lz4 => 0, + Compression::None => key.serialized_size_hint() + value.serialized_size_hint(), + } + } } #[derive(Debug)] diff --git a/foyer-storage/src/store.rs b/foyer-storage/src/store.rs index 5c9d804a..5293e1ad 100644 --- a/foyer-storage/src/store.rs +++ b/foyer-storage/src/store.rs @@ -144,7 +144,8 @@ where self.inner.write_runtime_handle.spawn(async move { if force || this.pick(entry.key()) { - let mut buffer = IoBytesMut::new(); + let mut buffer = + IoBytesMut::with_capacity(EntrySerializer::size_hint(entry.key(), entry.value(), &compression)); match EntrySerializer::serialize( entry.key(), entry.value(), From 22043fc95b41262f9771ad6ffccc40a08040a9ec Mon Sep 17 00:00:00 2001 From: Croxx Date: Mon, 9 Sep 2024 18:18:22 +0800 Subject: [PATCH 21/40] revert: "perf: introduce size hint for storage ... (#695)" (#696) This reverts commit 260ef1429a658fe8467530f3cd5d7cbae61cd5ee. --- foyer-common/src/code.rs | 18 ++++-------------- foyer-storage/src/serde.rs | 11 ----------- foyer-storage/src/store.rs | 3 +-- 3 files changed, 5 insertions(+), 27 deletions(-) diff --git a/foyer-common/src/code.rs b/foyer-common/src/code.rs index fb47b794..ae4826e6 100644 --- a/foyer-common/src/code.rs +++ b/foyer-common/src/code.rs @@ -25,23 +25,13 @@ impl Key for T {} impl Value for T {} /// Key trait for the disk cache. -pub trait StorageKey: Key + Serialize + DeserializeOwned + Hint {} -impl StorageKey for T where T: Key + Serialize + DeserializeOwned + Hint {} +pub trait StorageKey: Key + Serialize + DeserializeOwned {} +impl StorageKey for T where T: Key + Serialize + DeserializeOwned {} /// Value trait for the disk cache. -pub trait StorageValue: Value + 'static + Serialize + DeserializeOwned + Hint {} -impl StorageValue for T where T: Value + Serialize + DeserializeOwned + Hint {} +pub trait StorageValue: Value + 'static + Serialize + DeserializeOwned {} +impl StorageValue for T where T: Value + Serialize + DeserializeOwned {} /// Hash builder trait. pub trait HashBuilder: BuildHasher + Send + Sync + 'static {} impl HashBuilder for T where T: BuildHasher + Send + Sync + 'static {} - -/// Hint functions collection. -pub trait Hint { - /// Size hint for serialization. - fn serialized_size_hint(&self) -> usize { - 0 - } -} - -impl Hint for T {} diff --git a/foyer-storage/src/serde.rs b/foyer-storage/src/serde.rs index 93a87f38..89642226 100644 --- a/foyer-storage/src/serde.rs +++ b/foyer-storage/src/serde.rs @@ -94,17 +94,6 @@ impl EntrySerializer { Ok(KvInfo { key_len, value_len }) } - - pub fn size_hint<'a, K, V>(key: &'a K, value: &'a V, compression: &'a Compression) -> usize - where - K: StorageKey, - V: StorageValue, - { - match compression { - Compression::Zstd | Compression::Lz4 => 0, - Compression::None => key.serialized_size_hint() + value.serialized_size_hint(), - } - } } #[derive(Debug)] diff --git a/foyer-storage/src/store.rs b/foyer-storage/src/store.rs index 5293e1ad..5c9d804a 100644 --- a/foyer-storage/src/store.rs +++ b/foyer-storage/src/store.rs @@ -144,8 +144,7 @@ where self.inner.write_runtime_handle.spawn(async move { if force || this.pick(entry.key()) { - let mut buffer = - IoBytesMut::with_capacity(EntrySerializer::size_hint(entry.key(), entry.value(), &compression)); + let mut buffer = IoBytesMut::new(); match EntrySerializer::serialize( entry.key(), entry.value(), From ea88f87c6c4616ed3c1ef5e9f15b787b9e99623b Mon Sep 17 00:00:00 2001 From: Croxx Date: Tue, 10 Sep 2024 21:51:12 +0800 Subject: [PATCH 22/40] refactor: use bytesize for foyer-bench (#698) * refactor: use bytesize for foyer-bench Signed-off-by: MrCroxx * chore: fix ci Signed-off-by: MrCroxx * chore: switch bytesize repo to foyer-bytesize Signed-off-by: MrCroxx * fix: fix writer and reader units Signed-off-by: MrCroxx --------- Signed-off-by: MrCroxx --- .github/template/template.yml | 8 +-- .github/workflows/main.yml | 8 +-- .github/workflows/pull-request.yml | 8 +-- Cargo.toml | 1 + foyer-bench/Cargo.toml | 2 +- foyer-bench/src/main.rs | 88 +++++++++++++++--------------- foyer-cli/Cargo.toml | 2 +- 7 files changed, 59 insertions(+), 58 deletions(-) diff --git a/.github/template/template.yml b/.github/template/template.yml index f2fde5bb..2c6fdce6 100644 --- a/.github/template/template.yml +++ b/.github/template/template.yml @@ -191,7 +191,7 @@ jobs: CI: true run: | mkdir -p $GITHUB_WORKSPACE/foyer-data/foyer-bench/codecov - cargo llvm-cov --no-report run --package foyer-bench --bin foyer-bench --features "strict_assertions,sanity" -- --dir $GITHUB_WORKSPACE/foyer-data/foyer-bench/codecov --mem 16 --disk 256 --region-size 16 --get-range 1000 --w-rate 1 --r-rate 1 --admission-rate-limit 10 --time 60 + cargo llvm-cov --no-report run --package foyer-bench --bin foyer-bench --features "strict_assertions,sanity" -- --dir $GITHUB_WORKSPACE/foyer-data/foyer-bench/codecov --mem 16MiB --disk 256MiB --region-size 16MiB --get-range 1000 --w-rate 1MiB --r-rate 1MiB --admission-rate-limit 10MiB --time 60 - name: Generate codecov report run: | cargo llvm-cov report --lcov --output-path lcov.info @@ -231,7 +231,7 @@ jobs: run: |- cargo build --all --features deadlock mkdir -p $GITHUB_WORKSPACE/foyer-data/foyer-storage/deadlock - timeout 2m ./target/debug/foyer-bench --dir $GITHUB_WORKSPACE/foyer-data/foyer-bench/deadlock --mem 16 --disk 256 --region-size 16 --get-range 1000 --w-rate 1 --r-rate 1 --admission-rate-limit 10 --time 60 + timeout 2m ./target/debug/foyer-bench --dir $GITHUB_WORKSPACE/foyer-data/foyer-bench/deadlock --mem 16MiB --disk 256MiB --region-size 16MiB --get-range 1000 --w-rate 1MiB --r-rate 1MiB --admission-rate-limit 10MiB --time 60 asan: name: run with address saniziter runs-on: ubuntu-latest @@ -269,7 +269,7 @@ jobs: run: |- cargo +${{ env.RUST_TOOLCHAIN_NIGHTLY }} build --all --target x86_64-unknown-linux-gnu mkdir -p $GITHUB_WORKSPACE/foyer-data/foyer-bench/asan - timeout 2m ./target/x86_64-unknown-linux-gnu/debug/foyer-bench --dir $GITHUB_WORKSPACE/foyer-data/foyer-bench/asan --mem 16 --disk 256 --region-size 16 --get-range 1000 --w-rate 1 --r-rate 1 --admission-rate-limit 10 --time 60 + timeout 2m ./target/x86_64-unknown-linux-gnu/debug/foyer-bench --dir $GITHUB_WORKSPACE/foyer-data/foyer-bench/asan --mem 16MiB --disk 256MiB --region-size 16MiB --get-range 1000 --w-rate 1MiB --r-rate 1MiB --admission-rate-limit 10MiB --time 60 - name: Prepare Artifacts on Failure if: ${{ failure() }} run: |- @@ -317,7 +317,7 @@ jobs: run: |- cargo +${{ env.RUST_TOOLCHAIN_NIGHTLY }} build --all --target x86_64-unknown-linux-gnu mkdir -p $GITHUB_WORKSPACE/foyer-data/foyer-bench/lsan - timeout 2m ./target/x86_64-unknown-linux-gnu/debug/foyer-bench --dir $GITHUB_WORKSPACE/foyer-data/foyer-bench/lsan --mem 16 --disk 256 --region-size 16 --get-range 1000 --w-rate 1 --r-rate 1 --admission-rate-limit 10 --time 60 + timeout 2m ./target/x86_64-unknown-linux-gnu/debug/foyer-bench --dir $GITHUB_WORKSPACE/foyer-data/foyer-bench/lsan --mem 16MiB --disk 256MiB --region-size 16MiB --get-range 1000 --w-rate 1MiB --r-rate 1MiB --admission-rate-limit 10MiB --time 60 - name: Prepare Artifacts on Failure if: ${{ failure() }} run: |- diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1c03e6d2..aa42df1b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -197,7 +197,7 @@ jobs: CI: true run: | mkdir -p $GITHUB_WORKSPACE/foyer-data/foyer-bench/codecov - cargo llvm-cov --no-report run --package foyer-bench --bin foyer-bench --features "strict_assertions,sanity" -- --dir $GITHUB_WORKSPACE/foyer-data/foyer-bench/codecov --mem 16 --disk 256 --region-size 16 --get-range 1000 --w-rate 1 --r-rate 1 --admission-rate-limit 10 --time 60 + cargo llvm-cov --no-report run --package foyer-bench --bin foyer-bench --features "strict_assertions,sanity" -- --dir $GITHUB_WORKSPACE/foyer-data/foyer-bench/codecov --mem 16MiB --disk 256MiB --region-size 16MiB --get-range 1000 --w-rate 1MiB --r-rate 1MiB --admission-rate-limit 10MiB --time 60 - name: Generate codecov report run: | cargo llvm-cov report --lcov --output-path lcov.info @@ -237,7 +237,7 @@ jobs: run: |- cargo build --all --features deadlock mkdir -p $GITHUB_WORKSPACE/foyer-data/foyer-storage/deadlock - timeout 2m ./target/debug/foyer-bench --dir $GITHUB_WORKSPACE/foyer-data/foyer-bench/deadlock --mem 16 --disk 256 --region-size 16 --get-range 1000 --w-rate 1 --r-rate 1 --admission-rate-limit 10 --time 60 + timeout 2m ./target/debug/foyer-bench --dir $GITHUB_WORKSPACE/foyer-data/foyer-bench/deadlock --mem 16MiB --disk 256MiB --region-size 16MiB --get-range 1000 --w-rate 1MiB --r-rate 1MiB --admission-rate-limit 10MiB --time 60 asan: name: run with address saniziter runs-on: ubuntu-latest @@ -275,7 +275,7 @@ jobs: run: |- cargo +${{ env.RUST_TOOLCHAIN_NIGHTLY }} build --all --target x86_64-unknown-linux-gnu mkdir -p $GITHUB_WORKSPACE/foyer-data/foyer-bench/asan - timeout 2m ./target/x86_64-unknown-linux-gnu/debug/foyer-bench --dir $GITHUB_WORKSPACE/foyer-data/foyer-bench/asan --mem 16 --disk 256 --region-size 16 --get-range 1000 --w-rate 1 --r-rate 1 --admission-rate-limit 10 --time 60 + timeout 2m ./target/x86_64-unknown-linux-gnu/debug/foyer-bench --dir $GITHUB_WORKSPACE/foyer-data/foyer-bench/asan --mem 16MiB --disk 256MiB --region-size 16MiB --get-range 1000 --w-rate 1MiB --r-rate 1MiB --admission-rate-limit 10MiB --time 60 - name: Prepare Artifacts on Failure if: ${{ failure() }} run: |- @@ -323,7 +323,7 @@ jobs: run: |- cargo +${{ env.RUST_TOOLCHAIN_NIGHTLY }} build --all --target x86_64-unknown-linux-gnu mkdir -p $GITHUB_WORKSPACE/foyer-data/foyer-bench/lsan - timeout 2m ./target/x86_64-unknown-linux-gnu/debug/foyer-bench --dir $GITHUB_WORKSPACE/foyer-data/foyer-bench/lsan --mem 16 --disk 256 --region-size 16 --get-range 1000 --w-rate 1 --r-rate 1 --admission-rate-limit 10 --time 60 + timeout 2m ./target/x86_64-unknown-linux-gnu/debug/foyer-bench --dir $GITHUB_WORKSPACE/foyer-data/foyer-bench/lsan --mem 16MiB --disk 256MiB --region-size 16MiB --get-range 1000 --w-rate 1MiB --r-rate 1MiB --admission-rate-limit 10MiB --time 60 - name: Prepare Artifacts on Failure if: ${{ failure() }} run: |- diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index cfe463a2..66b24d86 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -196,7 +196,7 @@ jobs: CI: true run: | mkdir -p $GITHUB_WORKSPACE/foyer-data/foyer-bench/codecov - cargo llvm-cov --no-report run --package foyer-bench --bin foyer-bench --features "strict_assertions,sanity" -- --dir $GITHUB_WORKSPACE/foyer-data/foyer-bench/codecov --mem 16 --disk 256 --region-size 16 --get-range 1000 --w-rate 1 --r-rate 1 --admission-rate-limit 10 --time 60 + cargo llvm-cov --no-report run --package foyer-bench --bin foyer-bench --features "strict_assertions,sanity" -- --dir $GITHUB_WORKSPACE/foyer-data/foyer-bench/codecov --mem 16MiB --disk 256MiB --region-size 16MiB --get-range 1000 --w-rate 1MiB --r-rate 1MiB --admission-rate-limit 10MiB --time 60 - name: Generate codecov report run: | cargo llvm-cov report --lcov --output-path lcov.info @@ -236,7 +236,7 @@ jobs: run: |- cargo build --all --features deadlock mkdir -p $GITHUB_WORKSPACE/foyer-data/foyer-storage/deadlock - timeout 2m ./target/debug/foyer-bench --dir $GITHUB_WORKSPACE/foyer-data/foyer-bench/deadlock --mem 16 --disk 256 --region-size 16 --get-range 1000 --w-rate 1 --r-rate 1 --admission-rate-limit 10 --time 60 + timeout 2m ./target/debug/foyer-bench --dir $GITHUB_WORKSPACE/foyer-data/foyer-bench/deadlock --mem 16MiB --disk 256MiB --region-size 16MiB --get-range 1000 --w-rate 1MiB --r-rate 1MiB --admission-rate-limit 10MiB --time 60 asan: name: run with address saniziter runs-on: ubuntu-latest @@ -274,7 +274,7 @@ jobs: run: |- cargo +${{ env.RUST_TOOLCHAIN_NIGHTLY }} build --all --target x86_64-unknown-linux-gnu mkdir -p $GITHUB_WORKSPACE/foyer-data/foyer-bench/asan - timeout 2m ./target/x86_64-unknown-linux-gnu/debug/foyer-bench --dir $GITHUB_WORKSPACE/foyer-data/foyer-bench/asan --mem 16 --disk 256 --region-size 16 --get-range 1000 --w-rate 1 --r-rate 1 --admission-rate-limit 10 --time 60 + timeout 2m ./target/x86_64-unknown-linux-gnu/debug/foyer-bench --dir $GITHUB_WORKSPACE/foyer-data/foyer-bench/asan --mem 16MiB --disk 256MiB --region-size 16MiB --get-range 1000 --w-rate 1MiB --r-rate 1MiB --admission-rate-limit 10MiB --time 60 - name: Prepare Artifacts on Failure if: ${{ failure() }} run: |- @@ -322,7 +322,7 @@ jobs: run: |- cargo +${{ env.RUST_TOOLCHAIN_NIGHTLY }} build --all --target x86_64-unknown-linux-gnu mkdir -p $GITHUB_WORKSPACE/foyer-data/foyer-bench/lsan - timeout 2m ./target/x86_64-unknown-linux-gnu/debug/foyer-bench --dir $GITHUB_WORKSPACE/foyer-data/foyer-bench/lsan --mem 16 --disk 256 --region-size 16 --get-range 1000 --w-rate 1 --r-rate 1 --admission-rate-limit 10 --time 60 + timeout 2m ./target/x86_64-unknown-linux-gnu/debug/foyer-bench --dir $GITHUB_WORKSPACE/foyer-data/foyer-bench/lsan --mem 16MiB --disk 256MiB --region-size 16MiB --get-range 1000 --w-rate 1MiB --r-rate 1MiB --admission-rate-limit 10MiB --time 60 - name: Prepare Artifacts on Failure if: ${{ failure() }} run: |- diff --git a/Cargo.toml b/Cargo.toml index 5e705eae..367bb99b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,6 +33,7 @@ fastrace = "0.7" fastrace-jaeger = "0.7" fastrace-opentelemetry = "0.7" clap = { version = "4", features = ["derive"] } +bytesize = { package = "foyer-bytesize", version = "2" } [profile.release] debug = true diff --git a/foyer-bench/Cargo.toml b/foyer-bench/Cargo.toml index 0faff8a4..148bc258 100644 --- a/foyer-bench/Cargo.toml +++ b/foyer-bench/Cargo.toml @@ -12,7 +12,7 @@ readme = "../README.md" [dependencies] anyhow = "1" -bytesize = "1" +bytesize = { workspace = true } clap = { workspace = true } console-subscriber = { version = "0.4", optional = true } fastrace = { workspace = true, optional = true } diff --git a/foyer-bench/src/main.rs b/foyer-bench/src/main.rs index 98e69925..f72c30ea 100644 --- a/foyer-bench/src/main.rs +++ b/foyer-bench/src/main.rs @@ -31,7 +31,7 @@ use std::{ }; use analyze::{analyze, monitor, Metrics}; -use bytesize::MIB; +use bytesize::ByteSize; use clap::{builder::PossibleValuesParser, ArgGroup, Parser}; use foyer::{ Compression, DirectFileDeviceOptionsBuilder, DirectFsDeviceOptionsBuilder, FifoConfig, FifoPicker, HybridCache, @@ -73,13 +73,13 @@ pub struct Args { #[arg(short, long)] dir: Option, - /// In-memory cache capacity. (MiB) - #[arg(long, default_value_t = 1024)] - mem: usize, + /// In-memory cache capacity. + #[arg(long, default_value_t = ByteSize::gib(1))] + mem: ByteSize, - /// Disk cache capacity. (MiB) - #[arg(long, default_value_t = 1024)] - disk: usize, + /// Disk cache capacity. + #[arg(long, default_value_t = ByteSize::gib(1))] + disk: ByteSize, /// (s) #[arg(short, long, default_value_t = 60)] @@ -89,29 +89,29 @@ pub struct Args { #[arg(long, default_value_t = 2)] report_interval: u64, - /// Write rate limit per writer. (MiB) - #[arg(long, default_value_t = 0.0)] - w_rate: f64, + /// Write rate limit per writer. + #[arg(long, default_value_t = ByteSize::b(0))] + w_rate: ByteSize, - /// Read rate limit per reader. (MiB) - #[arg(long, default_value_t = 0.0)] - r_rate: f64, + /// Read rate limit per reader. + #[arg(long, default_value_t = ByteSize::b(0))] + r_rate: ByteSize, - /// Min entry size (B). - #[arg(long, default_value_t = 64 * 1024)] - entry_size_min: usize, + /// Min entry size. + #[arg(long, default_value_t = ByteSize::kib(64))] + entry_size_min: ByteSize, - /// Max entry size (B). - #[arg(long, default_value_t = 64 * 1024)] - entry_size_max: usize, + /// Max entry size. + #[arg(long, default_value_t = ByteSize::kib(64))] + entry_size_max: ByteSize, /// Reader lookup key range. #[arg(long, default_value_t = 10000)] get_range: u64, - /// Disk cache region size. (MiB) - #[arg(long, default_value_t = 64)] - region_size: usize, + /// Disk cache region size. + #[arg(long, default_value_t = ByteSize::mib(64))] + region_size: ByteSize, /// Flusher count. #[arg(long, default_value_t = 4)] @@ -136,13 +136,13 @@ pub struct Args { #[arg(long, default_value_t = 16)] recover_concurrency: usize, - /// Enable rated ticket admission picker if `admission_rate_limit > 0`. (MiB/s) - #[arg(long, default_value_t = 0)] - admission_rate_limit: usize, + /// Enable rated ticket admission picker if `admission_rate_limit > 0`. + #[arg(long, default_value_t = ByteSize::b(0))] + admission_rate_limit: ByteSize, - /// Enable rated ticket reinsertion picker if `reinsertion_rate_limit > 0`. (MiB/s) - #[arg(long, default_value_t = 0)] - reinsertion_rate_limit: usize, + /// Enable rated ticket reinsertion picker if `reinsertion_rate_limit > 0`. + #[arg(long, default_value_t = ByteSize::b(0))] + reinsertion_rate_limit: ByteSize, /// `0` means use default. #[arg(long, default_value_t = 0)] @@ -264,14 +264,14 @@ impl TimeSeriesDistribution { "uniform" => { // interval = 1 / freq = 1 / (rate / size) = size / rate let interval = - ((args.entry_size_min + args.entry_size_max) >> 1) as f64 / (args.w_rate * 1024.0 * 1024.0); + ((args.entry_size_min + args.entry_size_max).as_u64() >> 1) as f64 / (args.w_rate.as_u64() as f64); let interval = Duration::from_secs_f64(interval); TimeSeriesDistribution::Uniform { interval } } "zipf" => { // interval = 1 / freq = 1 / (rate / size) = size / rate let interval = - ((args.entry_size_min + args.entry_size_max) >> 1) as f64 / (args.w_rate * 1024.0 * 1024.0); + ((args.entry_size_min + args.entry_size_max).as_u64() >> 1) as f64 / (args.w_rate.as_u64() as f64); let interval = Duration::from_secs_f64(interval); display_zipf_sample(args.distribution_zipf_n, args.distribution_zipf_s); TimeSeriesDistribution::Zipf { @@ -431,7 +431,7 @@ async fn benchmark(args: Args) { let builder = HybridCacheBuilder::new() .with_tracing_config(tracing_config) - .memory(args.mem * MIB as usize) + .memory(args.mem.as_u64() as _) .with_shards(args.shards); let builder = match args.eviction.as_str() { @@ -453,14 +453,14 @@ async fn benchmark(args: Args) { builder = match (args.file.as_ref(), args.dir.as_ref()) { (Some(file), None) => builder.with_device_config( DirectFileDeviceOptionsBuilder::new(file) - .with_capacity(args.disk * MIB as usize) - .with_region_size(args.region_size * MIB as usize) + .with_capacity(args.disk.as_u64() as _) + .with_region_size(args.region_size.as_u64() as _) .build(), ), (None, Some(dir)) => builder.with_device_config( DirectFsDeviceOptionsBuilder::new(dir) - .with_capacity(args.disk * MIB as usize) - .with_file_size(args.region_size * MIB as usize) + .with_capacity(args.disk.as_u64() as _) + .with_file_size(args.region_size.as_u64() as _) .build(), ), _ => unreachable!(), @@ -497,13 +497,13 @@ async fn benchmark(args: Args) { _ => unreachable!(), }); - if args.admission_rate_limit > 0 { + if args.admission_rate_limit.as_u64() > 0 { builder = - builder.with_admission_picker(Arc::new(RateLimitPicker::new(args.admission_rate_limit * MIB as usize))); + builder.with_admission_picker(Arc::new(RateLimitPicker::new(args.admission_rate_limit.as_u64() as _))); } - if args.reinsertion_rate_limit > 0 { + if args.reinsertion_rate_limit.as_u64() > 0 { builder = - builder.with_reinsertion_picker(Arc::new(RateLimitPicker::new(args.admission_rate_limit * MIB as usize))); + builder.with_reinsertion_picker(Arc::new(RateLimitPicker::new(args.admission_rate_limit.as_u64() as _))); } if args.clean_region_threshold > 0 { @@ -570,15 +570,15 @@ async fn benchmark(args: Args) { } async fn bench(args: Args, hybrid: HybridCache, metrics: Metrics, stop_tx: broadcast::Sender<()>) { - let w_rate = if args.w_rate == 0.0 { + let w_rate = if args.w_rate.as_u64() == 0 { None } else { - Some(args.w_rate * 1024.0 * 1024.0) + Some(args.w_rate.as_u64() as _) }; - let r_rate = if args.r_rate == 0.0 { + let r_rate = if args.r_rate.as_u64() == 0 { None } else { - Some(args.r_rate * 1024.0 * 1024.0) + Some(args.r_rate.as_u64() as _) }; let counts = (0..args.writers).map(|_| AtomicU64::default()).collect_vec(); @@ -590,7 +590,7 @@ async fn bench(args: Args, hybrid: HybridCache, metrics: Metrics, st r_rate, get_range: args.get_range, counts, - entry_size_range: args.entry_size_min..args.entry_size_max + 1, + entry_size_range: args.entry_size_min.as_u64() as usize..args.entry_size_max.as_u64() as usize + 1, time: Duration::from_secs(args.time), warm_up: Duration::from_secs(args.warm_up), distribution, diff --git a/foyer-cli/Cargo.toml b/foyer-cli/Cargo.toml index 8d89b788..707677ff 100644 --- a/foyer-cli/Cargo.toml +++ b/foyer-cli/Cargo.toml @@ -12,7 +12,7 @@ readme = "../README.md" [dependencies] anyhow = "1" -bytesize = "1" +bytesize = { workspace = true } clap = { workspace = true } thiserror = "1" From 6615e5a32f0f42a7ec46d85c24cd6dfd51729c6c Mon Sep 17 00:00:00 2001 From: Croxx Date: Tue, 10 Sep 2024 22:23:42 +0800 Subject: [PATCH 23/40] chore: add ferris with foyer in logo (#700) Signed-off-by: MrCroxx --- etc/logo/ferris.min.svg | 1 + etc/logo/ferris.svg | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 etc/logo/ferris.min.svg create mode 100644 etc/logo/ferris.svg diff --git a/etc/logo/ferris.min.svg b/etc/logo/ferris.min.svg new file mode 100644 index 00000000..e5cee33f --- /dev/null +++ b/etc/logo/ferris.min.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/etc/logo/ferris.svg b/etc/logo/ferris.svg new file mode 100644 index 00000000..a4437bc3 --- /dev/null +++ b/etc/logo/ferris.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + From 636972d89eb10e93a04103b9dc019f35db77c4fc Mon Sep 17 00:00:00 2001 From: Croxx Date: Tue, 10 Sep 2024 22:54:01 +0800 Subject: [PATCH 24/40] chore: add ferris and foyer in readme (#701) * chore: add ferris and foyer in readme Signed-off-by: MrCroxx * chore: tiny refactor Signed-off-by: MrCroxx --------- Signed-off-by: MrCroxx --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 69223b42..4c4d39c9 100644 --- a/README.md +++ b/README.md @@ -210,6 +210,12 @@ Don't forget to pass `make fast` (which means fast check & test) locally before If you want to run a broader range of checks locally, run `make full`. 🙌 +Thank you for your contribution~ + +

+ +

+ ## Star History [![Star History Chart](https://api.star-history.com/svg?repos=foyer-rs/foyer&type=Date)](https://star-history.com/#foyer-rs/foyer&Date) \ No newline at end of file From fae86528705c190efb435bea178d9ec544c39b61 Mon Sep 17 00:00:00 2001 From: Bohan Zhang Date: Tue, 10 Sep 2024 23:31:21 +0800 Subject: [PATCH 25/40] fix: add `--locked` for `cargo-nextest` and `cargo-udeps` (#702) Signed-off-by: tabVersion Co-authored-by: Croxx --- scripts/install-deps.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/install-deps.sh b/scripts/install-deps.sh index 7e77a5b7..11c0e9e0 100755 --- a/scripts/install-deps.sh +++ b/scripts/install-deps.sh @@ -1,2 +1,3 @@ #!/bin/bash -cargo install cargo-sort cargo-nextest typos-cli cargo-udeps \ No newline at end of file +cargo install cargo-sort typos-cli +cargo install cargo-nextest cargo-udeps --locked \ No newline at end of file From 10c39537e12d156c2ee5fc6dc4ec7c66a9d45fef Mon Sep 17 00:00:00 2001 From: Croxx Date: Wed, 11 Sep 2024 13:59:04 +0800 Subject: [PATCH 26/40] chore: refine ci (#703) * chore: refine ci Signed-off-by: MrCroxx * trigger cancel * chore: rename ci workload file name Signed-off-by: MrCroxx * chore: enable ci on forks and rc Signed-off-by: MrCroxx --------- Signed-off-by: MrCroxx --- .github/template/generate.sh | 37 -- .github/template/main-override.yml | 6 - .github/template/pr-override.yml | 9 - .../template.yml => workflows/ci.yml} | 17 +- .github/workflows/main.yml | 343 ----------------- .github/workflows/pull-request.yml | 345 ------------------ Makefile | 3 - 7 files changed, 13 insertions(+), 747 deletions(-) delete mode 100755 .github/template/generate.sh delete mode 100644 .github/template/main-override.yml delete mode 100644 .github/template/pr-override.yml rename .github/{template/template.yml => workflows/ci.yml} (97%) delete mode 100644 .github/workflows/main.yml delete mode 100644 .github/workflows/pull-request.yml diff --git a/.github/template/generate.sh b/.github/template/generate.sh deleted file mode 100755 index 2d7e27c4..00000000 --- a/.github/template/generate.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash - -# You will need to install yq >= 4.16 to use this tool. -# brew install yq - -set -e - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" -cd "$DIR" - - -HEADER=""" -# ================= THIS FILE IS AUTOMATICALLY GENERATED ================= -# -# Please run generate.sh and commit after editing the workflow templates. -# -# ======================================================================== -""" - -# Generate workflow for main branch -echo "$HEADER" > ../workflows/main.yml -# shellcheck disable=SC2016 -yq ea '. as $item ireduce ({}; . * $item )' template.yml main-override.yml | yq eval '... comments=""' - >> ../workflows/main.yml -echo "$HEADER" >> ../workflows/main.yml - -# Generate workflow for pull requests -echo "$HEADER" > ../workflows/pull-request.yml -# shellcheck disable=SC2016 -yq ea '. as $item ireduce ({}; . * $item )' template.yml pr-override.yml | yq eval '... comments=""' - >> ../workflows/pull-request.yml -echo "$HEADER" >> ../workflows/pull-request.yml - -if [ "$1" == "--check" ] ; then - if ! git diff --exit-code; then - echo "Please run generate.sh and commit after editing the workflow templates." - exit 1 - fi -fi diff --git a/.github/template/main-override.yml b/.github/template/main-override.yml deleted file mode 100644 index 38fd29e7..00000000 --- a/.github/template/main-override.yml +++ /dev/null @@ -1,6 +0,0 @@ -name: CI (main) - -on: - push: - branches: [main] - workflow_dispatch: diff --git a/.github/template/pr-override.yml b/.github/template/pr-override.yml deleted file mode 100644 index f8c84881..00000000 --- a/.github/template/pr-override.yml +++ /dev/null @@ -1,9 +0,0 @@ -name: CI - -on: - pull_request: - branches: [main] - -concurrency: - group: environment-${{ github.ref }} - cancel-in-progress: true diff --git a/.github/template/template.yml b/.github/workflows/ci.yml similarity index 97% rename from .github/template/template.yml rename to .github/workflows/ci.yml index 2c6fdce6..c14a51b7 100644 --- a/.github/template/template.yml +++ b/.github/workflows/ci.yml @@ -1,6 +1,18 @@ -name: +name: "CI" on: + push: + branches: + - "main" + - "forks/*" + pull_request: + branches: + - "main" + - "v*.*.*-rc" + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} env: RUST_TOOLCHAIN_NIGHTLY: nightly-2024-07-19 @@ -25,9 +37,6 @@ jobs: BUF_VERSION: 1.0.0-rc6 - name: Install jq uses: dcarbone/install-jq-action@v2.0.2 - - name: Check if CI workflows are up-to-date - run: | - ./.github/template/generate.sh --check - name: Check if Grafana dashboards are minimized run: | ./scripts/minimize-dashboards.sh --check diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index aa42df1b..00000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,343 +0,0 @@ - -# ================= THIS FILE IS AUTOMATICALLY GENERATED ================= -# -# Please run generate.sh and commit after editing the workflow templates. -# -# ======================================================================== - -name: CI (main) -on: - push: - branches: [main] - workflow_dispatch: -env: - RUST_TOOLCHAIN_NIGHTLY: nightly-2024-07-19 - CARGO_TERM_COLOR: always - CACHE_KEY_SUFFIX: 20240821 -jobs: - misc-check: - name: misc check - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Run typos check - uses: crate-ci/typos@master - - name: Install yq - run: | - wget https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/${BINARY}.tar.gz -O - | tar xz && sudo mv ${BINARY} /usr/bin/yq - env: - YQ_VERSION: v4.16.1 - BINARY: yq_linux_amd64 - BUF_VERSION: 1.0.0-rc6 - - name: Install jq - uses: dcarbone/install-jq-action@v2.0.2 - - name: Check if CI workflows are up-to-date - run: | - ./.github/template/generate.sh --check - - name: Check if Grafana dashboards are minimized - run: | - ./scripts/minimize-dashboards.sh --check - - name: Run ShellCheck - uses: ludeeus/action-shellcheck@master - rust-udeps: - name: rust udeps test - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - runs-on: ${{ matrix.os }} - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Install rust toolchain - uses: dtolnay/rust-toolchain@master - with: - toolchain: nightly - - name: Cache Cargo home - uses: actions/cache@v4 - id: cache - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }}-${{ env.CACHE_KEY_SUFFIX }}-rust-udeps - - name: Install NASM for aws-lc-rs on Windows - if: runner.os == 'Windows' - uses: ilammy/setup-nasm@v1 - - name: Install ninja-build tool for aws-lc-fips-sys on Windows - if: runner.os == 'Windows' - uses: seanmiddleditch/gha-setup-ninja@v5 - - name: Install cargo-udeps - if: steps.cache.outputs.cache-hit != 'true' - run: | - cargo install cargo-udeps --locked - - name: Unused Dependencies Check - env: - RUSTFLAGS: "--cfg tokio_unstable -Awarnings" - run: | - cargo udeps --all-targets - rust-ffmt-check: - name: rust ffmt check - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - runs-on: ${{ matrix.os }} - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Install rust toolchain - uses: dtolnay/rust-toolchain@master - with: - toolchain: nightly - components: rustfmt - - name: Cache Cargo home - uses: actions/cache@v4 - id: cache - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }}-${{ env.CACHE_KEY_SUFFIX }}-rust-ffmt-check - - name: Fastidious Format Check - run: | - cargo fmt --all --check -- --config-path rustfmt.nightly.toml - - name: Hint - if: ${{ failure() }} - run: |- - echo "The ffmt (Fastidious Format Check) test is not a necessary." - echo "It uses unstable features to achieve a better format." - echo "If you want to pass the test, please install the nightly toolchain with \`rustup install nightly\`." - echo "Then run \`make ffmt\`." - rust-test: - name: rust test with codecov - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - rust_toolchain: [stable, 1.81.0] - runs-on: ${{ matrix.os }} - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Install rust toolchain - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ matrix.rust_toolchain }} - components: rustfmt, clippy, llvm-tools-preview - - name: Cache Cargo home - uses: actions/cache@v4 - id: cache - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }}-${{ env.CACHE_KEY_SUFFIX }}-rust-test - - name: Install cargo tools - if: steps.cache.outputs.cache-hit != 'true' - run: | - cargo install cargo-sort --locked - - name: Install NASM for aws-lc-rs on Windows - if: runner.os == 'Windows' - uses: ilammy/setup-nasm@v1 - - name: Install ninja-build tool for aws-lc-fips-sys on Windows - if: runner.os == 'Windows' - uses: seanmiddleditch/gha-setup-ninja@v5 - - name: Run rust cargo-sort check - if: matrix.os != 'windows-latest' - run: | - cargo sort -w -c - - name: Run rust format check - run: | - cargo fmt --all -- --check - - name: Run rust clippy check - run: | - cargo clippy --all-targets --features tokio-console -- -D warnings - cargo clippy --all-targets --features deadlock -- -D warnings - cargo clippy --all-targets --features mtrace -- -D warnings - cargo clippy --all-targets -- -D warnings - - if: steps.cache.outputs.cache-hit != 'true' - uses: taiki-e/install-action@cargo-llvm-cov - - if: steps.cache.outputs.cache-hit != 'true' - uses: taiki-e/install-action@nextest - - name: Run rust test with coverage (igored tests) - env: - RUST_BACKTRACE: 1 - CI: true - run: | - cargo llvm-cov --no-report nextest --run-ignored ignored-only --no-capture --workspace --features "strict_assertions,sanity" - - name: Run rust test with coverage - env: - RUST_BACKTRACE: 1 - CI: true - run: | - cargo llvm-cov --no-report nextest --features "strict_assertions,sanity" - - name: Run examples with coverage - env: - RUST_BACKTRACE: 1 - CI: true - run: | - cargo llvm-cov --no-report run --example memory - cargo llvm-cov --no-report run --example hybrid - cargo llvm-cov --no-report run --example hybrid_full - cargo llvm-cov --no-report run --example event_listener - cargo llvm-cov --no-report run --features "mtrace,jaeger" --example tail_based_tracing - cargo llvm-cov --no-report run --features "mtrace,ot" --example tail_based_tracing - - name: Run foyer-bench with coverage - if: runner.os == 'Linux' - env: - RUST_BACKTRACE: 1 - CI: true - run: | - mkdir -p $GITHUB_WORKSPACE/foyer-data/foyer-bench/codecov - cargo llvm-cov --no-report run --package foyer-bench --bin foyer-bench --features "strict_assertions,sanity" -- --dir $GITHUB_WORKSPACE/foyer-data/foyer-bench/codecov --mem 16MiB --disk 256MiB --region-size 16MiB --get-range 1000 --w-rate 1MiB --r-rate 1MiB --admission-rate-limit 10MiB --time 60 - - name: Generate codecov report - run: | - cargo llvm-cov report --lcov --output-path lcov.info - - uses: codecov/codecov-action@v4 - if: runner.os == 'Linux' && matrix.rust_toolchain == 'stable' - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - with: - verbose: true - deadlock: - name: run with single worker thread and deadlock detection - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Install rust toolchain - uses: dtolnay/rust-toolchain@master - with: - toolchain: stable - - name: Cache Cargo home - uses: actions/cache@v4 - id: cache - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }}-${{ env.CACHE_KEY_SUFFIX }}-deadlock - - name: Run foyer-bench with single worker thread and deadlock detection - env: - RUST_BACKTRACE: 1 - RUSTFLAGS: "--cfg tokio_unstable" - RUST_LOG: info - TOKIO_WORKER_THREADS: 1 - CI: true - run: |- - cargo build --all --features deadlock - mkdir -p $GITHUB_WORKSPACE/foyer-data/foyer-storage/deadlock - timeout 2m ./target/debug/foyer-bench --dir $GITHUB_WORKSPACE/foyer-data/foyer-bench/deadlock --mem 16MiB --disk 256MiB --region-size 16MiB --get-range 1000 --w-rate 1MiB --r-rate 1MiB --admission-rate-limit 10MiB --time 60 - asan: - name: run with address saniziter - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Install rust toolchain - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ env.RUST_TOOLCHAIN_NIGHTLY }} - - name: Cache Cargo home - uses: actions/cache@v4 - id: cache - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }}-${{ env.CACHE_KEY_SUFFIX }}-asan - - name: Run Unit Tests With Address Sanitizer - env: - RUST_BACKTRACE: 1 - RUSTFLAGS: "-Zsanitizer=address --cfg tokio_unstable" - RUST_LOG: info - CI: true - run: |- - cargo +${{ env.RUST_TOOLCHAIN_NIGHTLY }} test --lib --bins --tests --target x86_64-unknown-linux-gnu -- --nocapture - - name: Run foyer-bench With Address Sanitizer - env: - RUST_BACKTRACE: 1 - RUSTFLAGS: "-Zsanitizer=address --cfg tokio_unstable" - RUST_LOG: info - CI: true - run: |- - cargo +${{ env.RUST_TOOLCHAIN_NIGHTLY }} build --all --target x86_64-unknown-linux-gnu - mkdir -p $GITHUB_WORKSPACE/foyer-data/foyer-bench/asan - timeout 2m ./target/x86_64-unknown-linux-gnu/debug/foyer-bench --dir $GITHUB_WORKSPACE/foyer-data/foyer-bench/asan --mem 16MiB --disk 256MiB --region-size 16MiB --get-range 1000 --w-rate 1MiB --r-rate 1MiB --admission-rate-limit 10MiB --time 60 - - name: Prepare Artifacts on Failure - if: ${{ failure() }} - run: |- - find ./target/x86_64-unknown-linux-gnu/debug/ -type f -executable -name 'foyer*' -print0 | xargs -0 tar czvf artifacts.asan.tgz --transform 's#.*/##' - - name: Upload Artifacts on Failure - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: artifacts.asan.tgz - path: artifacts.asan.tgz - lsan: - name: run with leak saniziter - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Install rust toolchain - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ env.RUST_TOOLCHAIN_NIGHTLY }} - - name: Cache Cargo home - uses: actions/cache@v4 - id: cache - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }}-${{ env.CACHE_KEY_SUFFIX }}-lsan - - name: Run Unit Tests With Leak Sanitizer - env: - RUST_BACKTRACE: 1 - RUSTFLAGS: "-Zsanitizer=leak --cfg tokio_unstable" - RUST_LOG: info - CI: true - run: |- - cargo +${{ env.RUST_TOOLCHAIN_NIGHTLY }} test --lib --bins --tests --target x86_64-unknown-linux-gnu -- --nocapture - - name: Run foyer-bench With Leak Sanitizer - env: - RUST_BACKTRACE: 1 - RUSTFLAGS: "-Zsanitizer=leak --cfg tokio_unstable" - RUST_LOG: info - CI: true - run: |- - cargo +${{ env.RUST_TOOLCHAIN_NIGHTLY }} build --all --target x86_64-unknown-linux-gnu - mkdir -p $GITHUB_WORKSPACE/foyer-data/foyer-bench/lsan - timeout 2m ./target/x86_64-unknown-linux-gnu/debug/foyer-bench --dir $GITHUB_WORKSPACE/foyer-data/foyer-bench/lsan --mem 16MiB --disk 256MiB --region-size 16MiB --get-range 1000 --w-rate 1MiB --r-rate 1MiB --admission-rate-limit 10MiB --time 60 - - name: Prepare Artifacts on Failure - if: ${{ failure() }} - run: |- - find ./target/x86_64-unknown-linux-gnu/debug/ -type f -executable -name 'foyer*' -print0 | xargs -0 tar czvf artifacts.lsan.tgz --transform 's#.*/##' - - name: Upload Artifacts on Failure - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: artifacts.lsan.tgz - path: artifacts.lsan.tgz - -# ================= THIS FILE IS AUTOMATICALLY GENERATED ================= -# -# Please run generate.sh and commit after editing the workflow templates. -# -# ======================================================================== - diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml deleted file mode 100644 index 66b24d86..00000000 --- a/.github/workflows/pull-request.yml +++ /dev/null @@ -1,345 +0,0 @@ - -# ================= THIS FILE IS AUTOMATICALLY GENERATED ================= -# -# Please run generate.sh and commit after editing the workflow templates. -# -# ======================================================================== - -name: CI -on: - pull_request: - branches: [main] -env: - RUST_TOOLCHAIN_NIGHTLY: nightly-2024-07-19 - CARGO_TERM_COLOR: always - CACHE_KEY_SUFFIX: 20240821 -jobs: - misc-check: - name: misc check - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Run typos check - uses: crate-ci/typos@master - - name: Install yq - run: | - wget https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/${BINARY}.tar.gz -O - | tar xz && sudo mv ${BINARY} /usr/bin/yq - env: - YQ_VERSION: v4.16.1 - BINARY: yq_linux_amd64 - BUF_VERSION: 1.0.0-rc6 - - name: Install jq - uses: dcarbone/install-jq-action@v2.0.2 - - name: Check if CI workflows are up-to-date - run: | - ./.github/template/generate.sh --check - - name: Check if Grafana dashboards are minimized - run: | - ./scripts/minimize-dashboards.sh --check - - name: Run ShellCheck - uses: ludeeus/action-shellcheck@master - rust-udeps: - name: rust udeps test - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - runs-on: ${{ matrix.os }} - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Install rust toolchain - uses: dtolnay/rust-toolchain@master - with: - toolchain: nightly - - name: Cache Cargo home - uses: actions/cache@v4 - id: cache - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }}-${{ env.CACHE_KEY_SUFFIX }}-rust-udeps - - name: Install NASM for aws-lc-rs on Windows - if: runner.os == 'Windows' - uses: ilammy/setup-nasm@v1 - - name: Install ninja-build tool for aws-lc-fips-sys on Windows - if: runner.os == 'Windows' - uses: seanmiddleditch/gha-setup-ninja@v5 - - name: Install cargo-udeps - if: steps.cache.outputs.cache-hit != 'true' - run: | - cargo install cargo-udeps --locked - - name: Unused Dependencies Check - env: - RUSTFLAGS: "--cfg tokio_unstable -Awarnings" - run: | - cargo udeps --all-targets - rust-ffmt-check: - name: rust ffmt check - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - runs-on: ${{ matrix.os }} - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Install rust toolchain - uses: dtolnay/rust-toolchain@master - with: - toolchain: nightly - components: rustfmt - - name: Cache Cargo home - uses: actions/cache@v4 - id: cache - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }}-${{ env.CACHE_KEY_SUFFIX }}-rust-ffmt-check - - name: Fastidious Format Check - run: | - cargo fmt --all --check -- --config-path rustfmt.nightly.toml - - name: Hint - if: ${{ failure() }} - run: |- - echo "The ffmt (Fastidious Format Check) test is not a necessary." - echo "It uses unstable features to achieve a better format." - echo "If you want to pass the test, please install the nightly toolchain with \`rustup install nightly\`." - echo "Then run \`make ffmt\`." - rust-test: - name: rust test with codecov - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - rust_toolchain: [stable, 1.81.0] - runs-on: ${{ matrix.os }} - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Install rust toolchain - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ matrix.rust_toolchain }} - components: rustfmt, clippy, llvm-tools-preview - - name: Cache Cargo home - uses: actions/cache@v4 - id: cache - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }}-${{ env.CACHE_KEY_SUFFIX }}-rust-test - - name: Install cargo tools - if: steps.cache.outputs.cache-hit != 'true' - run: | - cargo install cargo-sort --locked - - name: Install NASM for aws-lc-rs on Windows - if: runner.os == 'Windows' - uses: ilammy/setup-nasm@v1 - - name: Install ninja-build tool for aws-lc-fips-sys on Windows - if: runner.os == 'Windows' - uses: seanmiddleditch/gha-setup-ninja@v5 - - name: Run rust cargo-sort check - if: matrix.os != 'windows-latest' - run: | - cargo sort -w -c - - name: Run rust format check - run: | - cargo fmt --all -- --check - - name: Run rust clippy check - run: | - cargo clippy --all-targets --features tokio-console -- -D warnings - cargo clippy --all-targets --features deadlock -- -D warnings - cargo clippy --all-targets --features mtrace -- -D warnings - cargo clippy --all-targets -- -D warnings - - if: steps.cache.outputs.cache-hit != 'true' - uses: taiki-e/install-action@cargo-llvm-cov - - if: steps.cache.outputs.cache-hit != 'true' - uses: taiki-e/install-action@nextest - - name: Run rust test with coverage (igored tests) - env: - RUST_BACKTRACE: 1 - CI: true - run: | - cargo llvm-cov --no-report nextest --run-ignored ignored-only --no-capture --workspace --features "strict_assertions,sanity" - - name: Run rust test with coverage - env: - RUST_BACKTRACE: 1 - CI: true - run: | - cargo llvm-cov --no-report nextest --features "strict_assertions,sanity" - - name: Run examples with coverage - env: - RUST_BACKTRACE: 1 - CI: true - run: | - cargo llvm-cov --no-report run --example memory - cargo llvm-cov --no-report run --example hybrid - cargo llvm-cov --no-report run --example hybrid_full - cargo llvm-cov --no-report run --example event_listener - cargo llvm-cov --no-report run --features "mtrace,jaeger" --example tail_based_tracing - cargo llvm-cov --no-report run --features "mtrace,ot" --example tail_based_tracing - - name: Run foyer-bench with coverage - if: runner.os == 'Linux' - env: - RUST_BACKTRACE: 1 - CI: true - run: | - mkdir -p $GITHUB_WORKSPACE/foyer-data/foyer-bench/codecov - cargo llvm-cov --no-report run --package foyer-bench --bin foyer-bench --features "strict_assertions,sanity" -- --dir $GITHUB_WORKSPACE/foyer-data/foyer-bench/codecov --mem 16MiB --disk 256MiB --region-size 16MiB --get-range 1000 --w-rate 1MiB --r-rate 1MiB --admission-rate-limit 10MiB --time 60 - - name: Generate codecov report - run: | - cargo llvm-cov report --lcov --output-path lcov.info - - uses: codecov/codecov-action@v4 - if: runner.os == 'Linux' && matrix.rust_toolchain == 'stable' - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - with: - verbose: true - deadlock: - name: run with single worker thread and deadlock detection - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Install rust toolchain - uses: dtolnay/rust-toolchain@master - with: - toolchain: stable - - name: Cache Cargo home - uses: actions/cache@v4 - id: cache - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }}-${{ env.CACHE_KEY_SUFFIX }}-deadlock - - name: Run foyer-bench with single worker thread and deadlock detection - env: - RUST_BACKTRACE: 1 - RUSTFLAGS: "--cfg tokio_unstable" - RUST_LOG: info - TOKIO_WORKER_THREADS: 1 - CI: true - run: |- - cargo build --all --features deadlock - mkdir -p $GITHUB_WORKSPACE/foyer-data/foyer-storage/deadlock - timeout 2m ./target/debug/foyer-bench --dir $GITHUB_WORKSPACE/foyer-data/foyer-bench/deadlock --mem 16MiB --disk 256MiB --region-size 16MiB --get-range 1000 --w-rate 1MiB --r-rate 1MiB --admission-rate-limit 10MiB --time 60 - asan: - name: run with address saniziter - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Install rust toolchain - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ env.RUST_TOOLCHAIN_NIGHTLY }} - - name: Cache Cargo home - uses: actions/cache@v4 - id: cache - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }}-${{ env.CACHE_KEY_SUFFIX }}-asan - - name: Run Unit Tests With Address Sanitizer - env: - RUST_BACKTRACE: 1 - RUSTFLAGS: "-Zsanitizer=address --cfg tokio_unstable" - RUST_LOG: info - CI: true - run: |- - cargo +${{ env.RUST_TOOLCHAIN_NIGHTLY }} test --lib --bins --tests --target x86_64-unknown-linux-gnu -- --nocapture - - name: Run foyer-bench With Address Sanitizer - env: - RUST_BACKTRACE: 1 - RUSTFLAGS: "-Zsanitizer=address --cfg tokio_unstable" - RUST_LOG: info - CI: true - run: |- - cargo +${{ env.RUST_TOOLCHAIN_NIGHTLY }} build --all --target x86_64-unknown-linux-gnu - mkdir -p $GITHUB_WORKSPACE/foyer-data/foyer-bench/asan - timeout 2m ./target/x86_64-unknown-linux-gnu/debug/foyer-bench --dir $GITHUB_WORKSPACE/foyer-data/foyer-bench/asan --mem 16MiB --disk 256MiB --region-size 16MiB --get-range 1000 --w-rate 1MiB --r-rate 1MiB --admission-rate-limit 10MiB --time 60 - - name: Prepare Artifacts on Failure - if: ${{ failure() }} - run: |- - find ./target/x86_64-unknown-linux-gnu/debug/ -type f -executable -name 'foyer*' -print0 | xargs -0 tar czvf artifacts.asan.tgz --transform 's#.*/##' - - name: Upload Artifacts on Failure - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: artifacts.asan.tgz - path: artifacts.asan.tgz - lsan: - name: run with leak saniziter - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Install rust toolchain - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ env.RUST_TOOLCHAIN_NIGHTLY }} - - name: Cache Cargo home - uses: actions/cache@v4 - id: cache - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }}-${{ env.CACHE_KEY_SUFFIX }}-lsan - - name: Run Unit Tests With Leak Sanitizer - env: - RUST_BACKTRACE: 1 - RUSTFLAGS: "-Zsanitizer=leak --cfg tokio_unstable" - RUST_LOG: info - CI: true - run: |- - cargo +${{ env.RUST_TOOLCHAIN_NIGHTLY }} test --lib --bins --tests --target x86_64-unknown-linux-gnu -- --nocapture - - name: Run foyer-bench With Leak Sanitizer - env: - RUST_BACKTRACE: 1 - RUSTFLAGS: "-Zsanitizer=leak --cfg tokio_unstable" - RUST_LOG: info - CI: true - run: |- - cargo +${{ env.RUST_TOOLCHAIN_NIGHTLY }} build --all --target x86_64-unknown-linux-gnu - mkdir -p $GITHUB_WORKSPACE/foyer-data/foyer-bench/lsan - timeout 2m ./target/x86_64-unknown-linux-gnu/debug/foyer-bench --dir $GITHUB_WORKSPACE/foyer-data/foyer-bench/lsan --mem 16MiB --disk 256MiB --region-size 16MiB --get-range 1000 --w-rate 1MiB --r-rate 1MiB --admission-rate-limit 10MiB --time 60 - - name: Prepare Artifacts on Failure - if: ${{ failure() }} - run: |- - find ./target/x86_64-unknown-linux-gnu/debug/ -type f -executable -name 'foyer*' -print0 | xargs -0 tar czvf artifacts.lsan.tgz --transform 's#.*/##' - - name: Upload Artifacts on Failure - uses: actions/upload-artifact@v4 - if: ${{ failure() }} - with: - name: artifacts.lsan.tgz - path: artifacts.lsan.tgz -concurrency: - group: environment-${{ github.ref }} - cancel-in-progress: true - -# ================= THIS FILE IS AUTOMATICALLY GENERATED ================= -# -# Please run generate.sh and commit after editing the workflow templates. -# -# ======================================================================== - diff --git a/Makefile b/Makefile index edb7c932..0c9c6fd6 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,6 @@ deps: check: typos shellcheck ./scripts/* - ./.github/template/generate.sh ./scripts/minimize-dashboards.sh cargo sort -w cargo fmt --all @@ -15,7 +14,6 @@ check: check-all: shellcheck ./scripts/* - ./.github/template/generate.sh ./scripts/minimize-dashboards.sh cargo sort -w cargo fmt --all @@ -53,7 +51,6 @@ fast: check test example msrv: shellcheck ./scripts/* - ./.github/template/generate.sh ./scripts/minimize-dashboards.sh cargo +1.81.0 sort -w cargo +1.81.0 fmt --all From 032c03981624cc6b6a13e022a42d31e727f800a5 Mon Sep 17 00:00:00 2001 From: Croxx Date: Wed, 11 Sep 2024 14:13:09 +0800 Subject: [PATCH 27/40] chore: fix ci badge in readme (#704) Signed-off-by: MrCroxx --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4c4d39c9..540169b9 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ ![Crates.io MSRV](https://img.shields.io/crates/msrv/foyer) ![GitHub License](https://img.shields.io/github/license/foyer-rs/foyer) -[![CI (main)](https://github.com/foyer-rs/foyer/actions/workflows/main.yml/badge.svg)](https://github.com/foyer-rs/foyer/actions/workflows/main.yml) +[![CI](https://github.com/foyer-rs/foyer/actions/workflows/ci.yml/badge.svg)](https://github.com/foyer-rs/foyer/actions/workflows/ci.yml) [![License Checker](https://github.com/foyer-rs/foyer/actions/workflows/license_check.yml/badge.svg)](https://github.com/foyer-rs/foyer/actions/workflows/license_check.yml) [![codecov](https://codecov.io/github/foyer-rs/foyer/branch/main/graph/badge.svg?token=YO33YQCB70)](https://codecov.io/github/foyer-rs/foyer) From a9d957ba7e4f875f52a918d642ce8fb9e4164fda Mon Sep 17 00:00:00 2001 From: Croxx Date: Thu, 12 Sep 2024 11:58:39 +0800 Subject: [PATCH 28/40] perf: use size hint on serde (#697) * perf: use size hint on serde Signed-off-by: MrCroxx * chore: make ffmt happy Signed-off-by: MrCroxx * chore: udeps Signed-off-by: MrCroxx --------- Signed-off-by: MrCroxx --- foyer-storage/Cargo.toml | 1 - foyer-storage/src/serde.rs | 31 +++++++++++++++++++++++++++++++ foyer-storage/src/store.rs | 2 +- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/foyer-storage/Cargo.toml b/foyer-storage/Cargo.toml index ff29e3a3..d181c4fe 100644 --- a/foyer-storage/Cargo.toml +++ b/foyer-storage/Cargo.toml @@ -29,7 +29,6 @@ foyer-memory = { version = "0.7.1", path = "../foyer-memory" } fs4 = "0.9.1" futures = "0.3" itertools = { workspace = true } -lazy_static = "1" libc = "0.2" lz4 = "1.24" parking_lot = { version = "0.12", features = ["arc_lock"] } diff --git a/foyer-storage/src/serde.rs b/foyer-storage/src/serde.rs index 89642226..0d19d5b0 100644 --- a/foyer-storage/src/serde.rs +++ b/foyer-storage/src/serde.rs @@ -15,6 +15,7 @@ use std::{fmt::Debug, hash::Hasher, time::Instant}; use foyer_common::{ + bits, code::{StorageKey, StorageValue}, metrics::Metrics, }; @@ -22,6 +23,7 @@ use twox_hash::XxHash64; use crate::{ compress::Compression, + device::ALIGN, error::{Error, Result}, IoBytesMut, }; @@ -94,6 +96,18 @@ impl EntrySerializer { Ok(KvInfo { key_len, value_len }) } + + pub fn size_hint<'a, K, V>(key: &'a K, value: &'a V) -> usize + where + K: StorageKey, + V: StorageValue, + { + let hint = match (bincode::serialized_size(key), bincode::serialized_size(value)) { + (Ok(k), Ok(v)) => (k + v) as usize, + _ => 0, + }; + bits::align_up(ALIGN, hint) + } } #[derive(Debug)] @@ -162,3 +176,20 @@ impl EntryDeserializer { } } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::test_utils::metrics_for_test; + + #[test] + fn test_serde_size_hint() { + let key = 42u64; + let value = vec![b'x'; 114514]; + let hint = EntrySerializer::size_hint(&key, &value); + let mut buf = IoBytesMut::new(); + EntrySerializer::serialize(&key, &value, &Compression::None, &mut buf, metrics_for_test()).unwrap(); + assert!(hint >= buf.len()); + assert!(hint.abs_diff(buf.len()) < ALIGN); + } +} diff --git a/foyer-storage/src/store.rs b/foyer-storage/src/store.rs index 5c9d804a..5ed47948 100644 --- a/foyer-storage/src/store.rs +++ b/foyer-storage/src/store.rs @@ -144,7 +144,7 @@ where self.inner.write_runtime_handle.spawn(async move { if force || this.pick(entry.key()) { - let mut buffer = IoBytesMut::new(); + let mut buffer = IoBytesMut::with_capacity(EntrySerializer::size_hint(entry.key(), entry.value())); match EntrySerializer::serialize( entry.key(), entry.value(), From ff588d4eb1a3ac247e9204b41f69b211d8925776 Mon Sep 17 00:00:00 2001 From: Croxx Date: Thu, 12 Sep 2024 12:40:47 +0800 Subject: [PATCH 29/40] feat: expose in-memory cache builder and cache entry (#705) Signed-off-by: MrCroxx --- foyer/src/prelude.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/foyer/src/prelude.rs b/foyer/src/prelude.rs index a3a6cd67..fd470ffd 100644 --- a/foyer/src/prelude.rs +++ b/foyer/src/prelude.rs @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -use ahash::RandomState; pub use common::{ buf::{BufExt, BufMutExt}, code::{Key, StorageKey, StorageValue, Value}, @@ -20,7 +19,10 @@ pub use common::{ range::RangeBoundsExt, tracing::TracingConfig, }; -pub use memory::{CacheContext, EvictionConfig, FetchState, FifoConfig, LfuConfig, LruConfig, S3FifoConfig, Weighter}; +pub use memory::{ + Cache, CacheBuilder, CacheContext, CacheEntry, EvictionConfig, FetchState, FifoConfig, LfuConfig, LruConfig, + S3FifoConfig, Weighter, +}; pub use storage::{ AdmissionPicker, AdmitAllPicker, Compression, Dev, DevExt, DevOptions, DeviceStats, DirectFileDevice, DirectFileDeviceOptions, DirectFileDeviceOptionsBuilder, DirectFsDevice, DirectFsDeviceOptions, @@ -35,8 +37,3 @@ pub use crate::hybrid::{ writer::{HybridCacheStorageWriter, HybridCacheWriter}, }; use crate::{common, memory, storage}; - -/// In-memory cache. -pub type Cache = memory::Cache; -/// In-memory cache builder. -pub type CacheBuilder = memory::CacheBuilder; From 1bafdfab68ebff8d18c03ead5af77909fc38f22c Mon Sep 17 00:00:00 2001 From: Croxx Date: Thu, 12 Sep 2024 15:24:23 +0800 Subject: [PATCH 30/40] chore: release foyer 0.11.2 (#706) * chore: release foyer 0.11.2 Signed-off-by: MrCroxx * chore: fix change log Signed-off-by: MrCroxx * chore: update readme Signed-off-by: MrCroxx --------- Signed-off-by: MrCroxx --- CHANGELOG.md | 24 ++++++++++++++++++++++++ README.md | 17 ++++++++++++----- foyer-bench/Cargo.toml | 4 ++-- foyer-common/Cargo.toml | 2 +- foyer-intrusive/Cargo.toml | 4 ++-- foyer-memory/Cargo.toml | 6 +++--- foyer-storage/Cargo.toml | 6 +++--- foyer/Cargo.toml | 8 ++++---- 8 files changed, 51 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f217e5c1..17b3fa6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,27 @@ +## 2024-09-12 + +| crate | version | +| - | - | +| foyer | 0.11.2 | +| foyer-common | 0.9.2 | +| foyer-intrusive | 0.9.2 | +| foyer-memory | 0.7.2 | +| foyer-storage | 0.10.2 | +| foyer-bench | 0.3.2 | + +
+ +### Changes + +- Support windows (for `foyer` only). +- Bump rust toolchain to `1.81.0`. +- Expose in-memory cache builder and cache entry. +- Reduce page fault and vec growth overhead. +- Use bytes size for `foyer-bench`. +- Fix install deps script. + +
+ ## 2024-08-31 | crate | version | diff --git a/README.md b/README.md index 540169b9..6ea75be1 100644 --- a/README.md +++ b/README.md @@ -196,6 +196,17 @@ More examples and details can be found [here](https://github.com/foyer-rs/foyer/ *foyer* is built against the recent stable release. The minimum supported version is 1.81.0. The current *foyer* version is not guaranteed to build on Rust versions earlier than the minimum supported version. +## Supported Platforms + +*foyer* is designed to serve on Linux OS, but can still be built on other OS for development. + +However, other components may not support non-Linux OS. + +| Component | Linux | MacOS | Windows | +| - | - | - | - | +| foyer | ✓ | ✓ | ✓ | +| foyer-bench | ✓ | ✗ | ✗ | + ## Development State & Roadmap Currently, *foyer* is still under heavy development. @@ -210,11 +221,7 @@ Don't forget to pass `make fast` (which means fast check & test) locally before If you want to run a broader range of checks locally, run `make full`. 🙌 -Thank you for your contribution~ - -

- -

+Thank you for your contribution~ ## Star History diff --git a/foyer-bench/Cargo.toml b/foyer-bench/Cargo.toml index 148bc258..c6bd15bc 100644 --- a/foyer-bench/Cargo.toml +++ b/foyer-bench/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "foyer-bench" -version = "0.3.1" +version = "0.3.2" edition = "2021" authors = ["MrCroxx "] description = "bench tool for foyer - the hybrid cache for Rust" @@ -17,7 +17,7 @@ clap = { workspace = true } console-subscriber = { version = "0.4", optional = true } fastrace = { workspace = true, optional = true } fastrace-jaeger = { workspace = true, optional = true } -foyer = { version = "0.11.1", path = "../foyer" } +foyer = { version = "0.11.2", path = "../foyer" } futures = "0.3" hdrhistogram = "7" itertools = { workspace = true } diff --git a/foyer-common/Cargo.toml b/foyer-common/Cargo.toml index 982448ed..bd9d5f37 100644 --- a/foyer-common/Cargo.toml +++ b/foyer-common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "foyer-common" -version = "0.9.1" +version = "0.9.2" edition = "2021" authors = ["MrCroxx "] description = "common components for foyer - the hybrid cache for Rust" diff --git a/foyer-intrusive/Cargo.toml b/foyer-intrusive/Cargo.toml index d2a980ef..598e35c5 100644 --- a/foyer-intrusive/Cargo.toml +++ b/foyer-intrusive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "foyer-intrusive" -version = "0.9.1" +version = "0.9.2" edition = "2021" authors = ["MrCroxx "] description = "intrusive data structures for foyer - the hybrid cache for Rust" @@ -11,7 +11,7 @@ readme = "../README.md" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -foyer-common = { version = "0.9.1", path = "../foyer-common" } +foyer-common = { version = "0.9.2", path = "../foyer-common" } itertools = { workspace = true } [features] diff --git a/foyer-memory/Cargo.toml b/foyer-memory/Cargo.toml index e2ea5a19..ba2ee1c0 100644 --- a/foyer-memory/Cargo.toml +++ b/foyer-memory/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "foyer-memory" -version = "0.7.1" +version = "0.7.2" edition = "2021" authors = ["MrCroxx "] description = "memory cache for foyer - the hybrid cache for Rust" @@ -15,8 +15,8 @@ ahash = "0.8" bitflags = "2" cmsketch = "0.2.1" fastrace = { workspace = true } -foyer-common = { version = "0.9.1", path = "../foyer-common" } -foyer-intrusive = { version = "0.9.1", path = "../foyer-intrusive" } +foyer-common = { version = "0.9.2", path = "../foyer-common" } +foyer-intrusive = { version = "0.9.2", path = "../foyer-intrusive" } futures = "0.3" hashbrown = "0.14" itertools = { workspace = true } diff --git a/foyer-storage/Cargo.toml b/foyer-storage/Cargo.toml index d181c4fe..1a2c365c 100644 --- a/foyer-storage/Cargo.toml +++ b/foyer-storage/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "foyer-storage" -version = "0.10.1" +version = "0.10.2" edition = "2021" authors = ["MrCroxx "] description = "storage engine for foyer - the hybrid cache for Rust" @@ -24,8 +24,8 @@ bytes = "1" clap = { workspace = true } either = "1" fastrace = { workspace = true } -foyer-common = { version = "0.9.1", path = "../foyer-common" } -foyer-memory = { version = "0.7.1", path = "../foyer-memory" } +foyer-common = { version = "0.9.2", path = "../foyer-common" } +foyer-memory = { version = "0.7.2", path = "../foyer-memory" } fs4 = "0.9.1" futures = "0.3" itertools = { workspace = true } diff --git a/foyer/Cargo.toml b/foyer/Cargo.toml index fecd526a..6c925596 100644 --- a/foyer/Cargo.toml +++ b/foyer/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "foyer" -version = "0.11.1" +version = "0.11.2" edition = "2021" authors = ["MrCroxx "] description = "Hybrid cache for Rust" @@ -15,9 +15,9 @@ rust-version = "1.81.0" ahash = "0.8" anyhow = "1" fastrace = { workspace = true } -foyer-common = { version = "0.9.1", path = "../foyer-common" } -foyer-memory = { version = "0.7.1", path = "../foyer-memory" } -foyer-storage = { version = "0.10.1", path = "../foyer-storage" } +foyer-common = { version = "0.9.2", path = "../foyer-common" } +foyer-memory = { version = "0.7.2", path = "../foyer-memory" } +foyer-storage = { version = "0.10.2", path = "../foyer-storage" } futures = "0.3" pin-project = "1" tokio = { workspace = true } From 7ce5be60f7626030a2e19cab3e712348057bcb69 Mon Sep 17 00:00:00 2001 From: Croxx Date: Sat, 14 Sep 2024 14:27:48 +0800 Subject: [PATCH 31/40] doc: remove details tag in change log for better searching (#711) Signed-off-by: MrCroxx --- CHANGELOG.md | 243 ++++++++++++++++++--------------------------------- 1 file changed, 84 insertions(+), 159 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 17b3fa6b..af62fc78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## 2024-09-12 +### Releases + | crate | version | | - | - | | foyer | 0.11.2 | @@ -9,8 +11,6 @@ | foyer-storage | 0.10.2 | | foyer-bench | 0.3.2 | -
- ### Changes - Support windows (for `foyer` only). @@ -20,10 +20,10 @@ - Use bytes size for `foyer-bench`. - Fix install deps script. -
- ## 2024-08-31 +### Releases + | crate | version | | - | - | | foyer | 0.11.1 | @@ -33,8 +33,6 @@ | foyer-storage | 0.10.1 | | foyer-bench | 0.3.1 | -
- ### Changes - Add metrics for serde. @@ -43,10 +41,10 @@ - Implement `Default` for `TokioRuntimeConfig`. - Fix typos and format code with unstable features. -
- ## 2024-08-21 +### Releases + | crate | version | | - | - | | foyer | 0.11.0 | @@ -56,8 +54,6 @@ | foyer-storage | 0.10.0 | | foyer-bench | 0.3.0 | -
- ### Changes - Support disk cache on raw block device. @@ -69,42 +65,38 @@ - Update `foyer-bench` with more fine-grained configurations. - Fix panics with `None` recover mode. -
- ## 2024-08-15 +### Releases + | crate | version | | - | - | | foyer | 0.10.4 | | foyer-storage | 0.9.3 | | foyer-bench | 0.2.3 | -
- ### Changes - Support serde for recover mode configuration. -
- ## 2024-08-14 +### Releases + | crate | version | | - | - | | foyer | 0.10.2 | | foyer-storage | 0.9.2 | | foyer-bench | 0.2.2 | -
- ### Changes - Fix panic with "none" recovery mode. -
- ## 2024-07-08 +### Releases + | crate | version | | - | - | | foyer | 0.10.1 | @@ -114,16 +106,14 @@ | foyer-storage | 0.9.1 | | foyer-bench | 0.2.1 | -
- ### Changes - Refine write model, make flush buffer threshold configurable to mitigate memory usage spike and OOM. -
- ## 2024-07-02 +### Releases + | crate | version | | - | - | | foyer | 0.10.0 | @@ -133,37 +123,33 @@ | foyer-storage | 0.9.0 | | foyer-bench | 0.2.0 | -
- ### Changes - Introduce tail-based tracing framework with [minitrace](https://github.com/tikv/minitrace-rust). [Tail-based Tracing Example](https://github.com/foyer-rs/foyer/tree/main/examples/tail_based_tracing.rs). - Fix `fetch()` disk cache refill on in-memory cache miss. - Publish *foyer* logo! - - -
+ ## 2024-06-14 +### Releases + | crate | version | | - | - | | foyer | 0.9.4 | | foyer-storage | 0.8.5 | | foyer-bench | 0.1.4 | -
- ### Changes - Fix phantom entries after foyer storage recovery. [#560](https://github.com/foyer-rs/foyer/pull/560) - Fix hybrid cache hit metrics with `fetch()` interface. [#563](https://github.com/foyer-rs/foyer/pull/563) -
- ## 2024-06-05 +### Releases + | crate | version | | - | - | | foyer | 0.9.3 | @@ -173,31 +159,27 @@ | foyer-storage | 0.8.4 | | foyer-bench | 0.1.3 | -
- ### Changes - Hybrid cache `fetch()` use the dedicated runtime by default if enabled. - Separate `fetch()` and `fetch_with_runtime()` interface for in-memory cache. -
- ## 2024-06-04 +### Releases + | crate | version | | - | - | | foyer-storage | 0.8.3 | -
- ### Changes - Fix "invalid argument (code: 22)" on target aarch64. -
- ## 2024-06-03 +### Releases + | crate | version | | - | - | | foyer | 0.9.2 | @@ -207,16 +189,14 @@ | foyer-storage | 0.8.2 | | foyer-bench | 0.1.2 | -
- ### Changes - Support customized cache event listener. -
- ## 2024-05-31 +### Releases + | crate | version | | - | - | | foyer | 0.9.1 | @@ -226,8 +206,6 @@ | foyer-storage | 0.8.1 | | foyer-bench | 0.1.1 | -
- ### Changes - Fix "attempt to subtract with overflow" panic after cloning cache entry. [#543](https://github.com/foyer-rs/foyer/issues/543). @@ -240,10 +218,10 @@ - Remove `pop()` related interface from the in-memory cache. - Refine intrusive data structure implementation. -
- ## 2024-05-27 +### Releases + | crate | version | | - | - | | foyer | 0.9.0 | @@ -253,8 +231,6 @@ | foyer-storage | 0.8.0 | | foyer-bench | 0.1.0 | -
- ### Changes - Refine the storage engine to reduce the overhead and boost the performance. @@ -267,10 +243,10 @@ - Reduce unnecessary dependencies. - More details: [foyer - Development Roadmap](https://github.com/orgs/foyer-rs/projects/2). -
- ## 2024-04-28 +### Releases + | crate | version | | - | - | | foyer | 0.8.9 | @@ -279,17 +255,15 @@ | foyer-storage | 0.7.6 | | foyer-storage-bench | 0.7.5 | -
- ### Changes - feat: Add config to control the recover mode. - feat: Add config to enable/disable direct i/o. (Enabled by default for large entries optimization.) -
- ## 2024-04-28 +### Releases + | crate | version | | - | - | | foyer | 0.8.8 | @@ -297,60 +271,52 @@ | foyer-storage | 0.7.5 | | foyer-storage-bench | 0.7.4 | -
- ### Changes - feat: Impl `Debug` for `HybridCache`. - feat: Impl `serde`, `Default` for eviction configs. - refactor: Add internal trait `EvictionConfig` to bound eviction algorithm configs. -
- ## 2024-04-27 +### Releases + | crate | version | | - | - | | foyer | 0.8.7 | -
- ### Changes - Make `HybridCache` clonable. -
- ## 2024-04-27 +### Releases + | crate | version | | - | - | | foyer-memory | 0.3.4 | -
- ### Changes - Fix S3FIFO ghost queue. -
- ## 2024-04-26 +### Releases + | crate | version | | - | - | | foyer-storage | 0.7.4 | -
- ### Changes - Fix `FsDeviceBuilder` on a non-exist directory without capacity given. -
- ## 2024-04-26 +### Releases + | crate | version | | - | - | | foyer | 0.8.6 | @@ -360,23 +326,19 @@ | foyer-storage | 0.7.3 | | foyer-storage-bench | 0.7.3 | -
- ### Changes - Remove unused dependencies. - Remove hakari workspace hack. -
- ## 2024-04-26 +### Releases + | crate | version | | - | - | | foyer | 0.8.5 | -
- ### Changes - Expose `EntryState`, `HybridEntry`. @@ -385,38 +347,34 @@ - Re-export `ahash::RandomState`. - Loose `entry()` args trait bounds. -
- ## 2024-04-25 +### Releases + | crate | version | | - | - | | foyer | 0.8.4 | -
- ### Changes - Expose `HybridCacheEntry`. -
- ## 2024-04-25 +### Releases + | crate | version | | - | - | | foyer | 0.8.3 | -
- ### Changes - Expose `Key`, `Value`, `StorageKey`, `StorageValue` traits. -
- ## 2024-04-24 +### Releases + | crate | version | | - | - | | foyer | 0.8.2 | @@ -427,16 +385,14 @@ | foyer-storage-bench | 0.7.2 | | foyer-workspace-hack | 0.5.2 | -
- ### Changes - Add `nightly` feature to make it compatible with night toolchain. -
- ## 2024-04-24 +### Releases + | crate | version | | - | - | | foyer | 0.8.1 | @@ -447,18 +403,16 @@ | foyer-storage-bench | 0.7.1 | | foyer-workspace-hack | 0.5.1 | -
- ### Changes - Add `with_flush` to enable flush for each io. - Loose MSRV to 1.76 . - Flush the device on store close. -
- ## 2024-04-23 +### Releases + | crate | version | | - | - | | foyer | 0.8.0 | @@ -469,8 +423,6 @@ | foyer-storage-bench | 0.7.0 | | foyer-workspace-hack | 0.5.0 | -
- ### Changes - Combine in-memory cache and disk cache into `HybridCache`. @@ -482,10 +434,10 @@ - Fix S3FIFO eviction bugs. - Add more examples. -
- ## 2024-04-11 +### Releases + | crate | version | | - | - | | foyer | 0.7.0 | @@ -496,90 +448,78 @@ | foyer-storage-bench | 0.6.0 | | foyer-workspace-hack | 0.4.0 | -
- ### Changes - Make `foyer` compatible with rust stable toolchain (MSRV = 1.77.2). 🎉 -
- ## 2024-04-09 +### Releases + | crate | version | | - | - | | foyer-storage | 0.5.1 | | foyer-memory | 0.1.4 | -
- ### Changes - fix: Fix panics on `state()` for s3fifo entry. - fix: Enable `offset_of` feature for `foyer-storage`. -
- ## 2024-04-08 +### Releases + | crate | version | | - | - | | foyer-intrusive | 0.3.1 | | foyer-memory | 0.1.3 | -
- ### Changes - feat: Introduce s3fifo to `foyer-memory`. - fix: Fix doctest for `foyer-intrusive`. -
- ## 2024-03-21 +### Releases + | crate | version | | - | - | | foyer-memory | 0.1.2 | -
- ### Changes - fix: `foyer-memory` export `DefaultCacheEventListener`. -
- ## 2024-03-14 +### Releases + | crate | version | | - | - | | foyer-memory | 0.1.1 | -
- ### Changes - Make eviction config clonable. -
- ## 2024-03-13 +### Releases + | crate | version | | - | - | | foyer-storage-bench | 0.5.1 | -
- ### Changes - Fix `foyer-storage-bench` build with `trace` feature. -
- ## 2024-03-12 +### Releases + | crate | version | | - | - | | foyer | 0.6.0 | @@ -590,17 +530,15 @@ | foyer-storage-bench | 0.5.0 | | foyer-workspace-hack | 0.3.0 | -
- ### Changes - Release foyer in-memory cache as crate `foyer-memory`. - Bump other components with changes. -
- ## 2023-12-28 +### Releases + | crate | version | | - | - | | foyer | 0.5.0 | @@ -610,21 +548,16 @@ | foyer-storage-bench | 0.4.0 | | foyer-workspace-hack | 0.2.0 | -
- ### Changes - Bump rust-toolchain to "nightly-2023-12-26". - Introduce time-series distribution args to bench tool. [#253](https://github.com/foyer-rs/foyer/pull/253) - -### Fixes - - Fix duplicated insert drop metrics. -
- ## 2023-12-22 +### Releases + | crate | version | | - | - | | foyer | 0.4.0 | @@ -632,45 +565,40 @@ | foyer-storage-bench | 0.3.0 | | foyer-workspace-hack | 0.1.1 | -
- ### Changes - Remove config `flusher_buffer_capacity`. - -### Fixes - - Fix benchmark tool cache miss ratio. -
- ## 2023-12-20 +### Releases + | crate | version | | - | - | | foyer-storage | 0.2.2 | -
+### Changes - Fix metrics for writer dropping. - Add interface `insert_async_with_callback` and `insert_if_not_exists_async_with_callback` for callers to get the insert result. -
- ## 2023-12-18 +### Releases + | crate | version | | - | - | | foyer-storage | 0.2.1 | -
+### Changes - Introduce the entry size histogram, update metrics. -
- ## 2023-12-18 +### Releases + | crate | version | | - | - | | foyer | 0.3.0 | @@ -678,16 +606,16 @@ | foyer-storage | 0.2.0 | | foyer-storage-bench | 0.2.0 | -
+### Changes - Introduce the associated type `Cursor` for trait `Key` and `Value` to reduce unnecessary buffer copy if possible. - Remove the ring buffer and continuum tracker for they are no longer needed. - Update the configuration of the storage engine and the benchmark tool. -
- ## 2023-11-29 +### Releases + | crate | version | | - | - | | foyer | 0.2.0 | @@ -697,7 +625,7 @@ | foyer-storage-bench | 0.1.0 | | foyer-workspace-hack | 0.1.0 | -
+### Changes The first version that can be used as file cache. @@ -715,17 +643,14 @@ Brief description about the subcrates: - foyer-storage-bench: Runnable benchmark tool for the file cache storage engine. - foyer-workspace-hack: Generated by [hakari](https://crates.io/crates/hakari) to prevent building each crate from triggering building from scratch. -
- - ## 2023-05-12 +### Releases + | crate | version | | - | - | | foyer | 0.1.0 | -
+### Changes Initial version with just basic interfaces. - -
From 4878ef25eb4d6cfe42802e26d82096ba1174658c Mon Sep 17 00:00:00 2001 From: Croxx Date: Sat, 14 Sep 2024 22:57:06 +0800 Subject: [PATCH 32/40] chore: add some metadata for changelog (#712) * chore: add some metadata for changelog Signed-off-by: MrCroxx * chore: add more meta Signed-off-by: MrCroxx * chore: just more Signed-off-by: MrCroxx --------- Signed-off-by: MrCroxx --- CHANGELOG.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index af62fc78..327c191f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,24 @@ +--- +title: Changelog +description: Changelog for foyer. +authors: + - name: Croxx + title: Author of foyer + url: https://github.com/mrcroxx + image_url: https://github.com/mrcroxx.png + socials: + x: CroxxMr + github: mrcroxx + linkedin: mrcroxx + newsletter: https://blog.mrcroxx.com +tags: [changelog] +date: 2023-05-12T11:02:09+08:00 +--- + +# Changelog + + + ## 2024-09-12 ### Releases From 714b3c3d64ff1104b94384a0bfcaf986b3c60978 Mon Sep 17 00:00:00 2001 From: Croxx Date: Sat, 14 Sep 2024 23:18:11 +0800 Subject: [PATCH 33/40] chore: ignore changelog author details (#713) Signed-off-by: MrCroxx --- CHANGELOG.md | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 327c191f..47a2dd24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,16 +1,7 @@ --- title: Changelog description: Changelog for foyer. -authors: - - name: Croxx - title: Author of foyer - url: https://github.com/mrcroxx - image_url: https://github.com/mrcroxx.png - socials: - x: CroxxMr - github: mrcroxx - linkedin: mrcroxx - newsletter: https://blog.mrcroxx.com +authors: mrcroxx tags: [changelog] date: 2023-05-12T11:02:09+08:00 --- From c28c6c1a81c793ce3d20c4ba73943a01df47f0c9 Mon Sep 17 00:00:00 2001 From: Croxx Date: Thu, 19 Sep 2024 14:24:15 +0800 Subject: [PATCH 34/40] chore: update readme, add website (#719) Signed-off-by: MrCroxx --- README.md | 24 +++++++++++++++++++----- foyer/src/lib.rs | 4 ++++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 6ea75be1..a878d205 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,18 @@

+
+ +![Website](https://img.shields.io/website?url=https%3A%2F%2Ffoyer.rs&up_message=foyer.rs&style=for-the-badge&logo=rust&labelColor=555555) +![Crates.io Version](https://img.shields.io/crates/v/foyer?style=for-the-badge&logo=docs.rs&labelColor=555555) +![docs.rs](https://img.shields.io/docsrs/foyer?style=for-the-badge&logo=docs.rs&labelColor=555555) + +
+ # foyer -![Crates.io Version](https://img.shields.io/crates/v/foyer) -![Crates.io MSRV](https://img.shields.io/crates/msrv/foyer) ![GitHub License](https://img.shields.io/github/license/foyer-rs/foyer) - +![Crates.io MSRV](https://img.shields.io/crates/msrv/foyer) [![CI](https://github.com/foyer-rs/foyer/actions/workflows/ci.yml/badge.svg)](https://github.com/foyer-rs/foyer/actions/workflows/ci.yml) [![License Checker](https://github.com/foyer-rs/foyer/actions/workflows/license_check.yml/badge.svg)](https://github.com/foyer-rs/foyer/actions/workflows/license_check.yml) [![codecov](https://codecov.io/github/foyer-rs/foyer/branch/main/graph/badge.svg?token=YO33YQCB70)](https://codecov.io/github/foyer-rs/foyer) @@ -18,9 +24,11 @@ foyer draws inspiration from [Facebook/CacheLib](https://github.com/facebook/cac However, *foyer* is more than just a *rewrite in Rust* effort; it introduces a variety of new and optimized features. +For more details, please visit foyer's website: https://foyer.rs 🥰 + ## Features -- **Hybrid Cache**: Seamlessly integrates both in-memory and disk-based caching for optimal performance and flexibility. +- **Hybrid Cache**: Seamlessly integrates both in-memory and disk cache for optimal performance and flexibility. - **Plug-and-Play Algorithms**: Empowers users with easily replaceable caching algorithms, ensuring adaptability to diverse use cases. - **Fearless Concurrency**: Built to handle high concurrency with robust thread-safe mechanisms, guaranteeing reliable performance under heavy loads. - **Zero-Copy In-Memory Cache Abstraction**: Leveraging Rust's robust type system, the in-memory cache in foyer achieves a better performance with zero-copy abstraction. @@ -34,7 +42,13 @@ Feel free to open a PR and add your projects here: - [RisingWave](https://github.com/risingwavelabs/risingwave): SQL stream processing, analytics, and management. - [Chroma](https://github.com/chroma-core/chroma): Embedding database for LLM apps. -## Usage +## Document + +Tutorial & Document: https://foyer.rs + +API References: https://docs.rs/foyer + +## Quick Start To use *foyer* in your project, add this line to the `dependencies` section of `Cargo.toml`. diff --git a/foyer/src/lib.rs b/foyer/src/lib.rs index dc0710cd..27a1f61f 100644 --- a/foyer/src/lib.rs +++ b/foyer/src/lib.rs @@ -17,6 +17,10 @@ #![warn(clippy::allow_attributes)] //! A hybrid cache library that supports plug-and-play cache algorithms, in-memory cache and disk cache. +//! +//! ![Crates.io Version](https://img.shields.io/crates/v/foyer?style=for-the-badge&logo=docs.rs&labelColor=555555) +//! ![docs.rs](https://img.shields.io/docsrs/foyer?style=for-the-badge&logo=docs.rs&labelColor=555555) +//! ![Website](https://img.shields.io/website?url=https%3A%2F%2Ffoyer.rs&up_message=foyer.rs&style=for-the-badge&logo=rust&labelColor=555555) use foyer_common as common; use foyer_memory as memory; From 474fd2fe7da36e77b859bd59cc5ea60ef1598cef Mon Sep 17 00:00:00 2001 From: Croxx Date: Thu, 19 Sep 2024 17:33:51 +0800 Subject: [PATCH 35/40] chore: update badge with link (#721) * chore: update badge with link Signed-off-by: MrCroxx * chore: center the badges Signed-off-by: MrCroxx * chore: add website center Signed-off-by: MrCroxx * chore: fix link Signed-off-by: MrCroxx * chore: add more guides Signed-off-by: MrCroxx * chore: add links in rust doc Signed-off-by: MrCroxx * chore: update Signed-off-by: MrCroxx --------- Signed-off-by: MrCroxx --- README.md | 34 ++++++++++++++++++++++------------ foyer/src/lib.rs | 11 ++++++++--- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index a878d205..eb639ae5 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,22 @@

-
- -![Website](https://img.shields.io/website?url=https%3A%2F%2Ffoyer.rs&up_message=foyer.rs&style=for-the-badge&logo=rust&labelColor=555555) -![Crates.io Version](https://img.shields.io/crates/v/foyer?style=for-the-badge&logo=docs.rs&labelColor=555555) -![docs.rs](https://img.shields.io/docsrs/foyer?style=for-the-badge&logo=docs.rs&labelColor=555555) +

+ + docs.rs + + + crates.io + + + docs.rs + +

-
+

+ Tutorial & Document: + https://foyer.rs +

# foyer @@ -26,6 +35,11 @@ However, *foyer* is more than just a *rewrite in Rust* effort; it introduces a v For more details, please visit foyer's website: https://foyer.rs 🥰 +[Website](https://foyer.rs) | +[Tutorial](https://foyer.rs/docs/overview) | +[API Docs](https://docs.rs/foyer) | +[Crate](https://crates.io/crates/foyer) + ## Features - **Hybrid Cache**: Seamlessly integrates both in-memory and disk cache for optimal performance and flexibility. @@ -42,14 +56,10 @@ Feel free to open a PR and add your projects here: - [RisingWave](https://github.com/risingwavelabs/risingwave): SQL stream processing, analytics, and management. - [Chroma](https://github.com/chroma-core/chroma): Embedding database for LLM apps. -## Document - -Tutorial & Document: https://foyer.rs - -API References: https://docs.rs/foyer - ## Quick Start +**This section only shows briefs. Please visit https://foyer.rs for more details.** + To use *foyer* in your project, add this line to the `dependencies` section of `Cargo.toml`. ```toml diff --git a/foyer/src/lib.rs b/foyer/src/lib.rs index 27a1f61f..2a636cd5 100644 --- a/foyer/src/lib.rs +++ b/foyer/src/lib.rs @@ -18,9 +18,14 @@ //! A hybrid cache library that supports plug-and-play cache algorithms, in-memory cache and disk cache. //! -//! ![Crates.io Version](https://img.shields.io/crates/v/foyer?style=for-the-badge&logo=docs.rs&labelColor=555555) -//! ![docs.rs](https://img.shields.io/docsrs/foyer?style=for-the-badge&logo=docs.rs&labelColor=555555) -//! ![Website](https://img.shields.io/website?url=https%3A%2F%2Ffoyer.rs&up_message=foyer.rs&style=for-the-badge&logo=rust&labelColor=555555) +//! ![Website](https://img.shields.io/website?url=https%3A%2F%2Ffoyer.rs&up_message=foyer.rs&down_message=website&style=for-the-badge&logo=htmx&link=https%3A%2F%2Ffoyer.rs) +//! ![Crates.io Version](https://img.shields.io/crates/v/foyer?style=for-the-badge&logo=crates.io&labelColor=555555&link=https%3A%2F%2Fcrates.io%2Fcrates%2Ffoyer) +//! ![docs.rs](https://img.shields.io/docsrs/foyer?style=for-the-badge&logo=rust&label=docs.rs&labelColor=555555&link=https%3A%2F%2Fdocs.rs%2Ffoyer) +//! +//! [Website](https://foyer.rs) | +//! [Tutorial](https://foyer.rs/docs/overview) | +//! [API Docs](https://docs.rs/foyer) | +//! [Crate](https://crates.io/crates/foyer) use foyer_common as common; use foyer_memory as memory; From 7ebc971d2c1542382e7ea2c2008c5083b3fede41 Mon Sep 17 00:00:00 2001 From: Croxx Date: Fri, 20 Sep 2024 12:26:09 +0800 Subject: [PATCH 36/40] fix: fix io buffer pool alignment (#724) Signed-off-by: MrCroxx --- foyer-storage/src/io_buffer_pool.rs | 5 ++++- foyer-storage/src/large/batch.rs | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/foyer-storage/src/io_buffer_pool.rs b/foyer-storage/src/io_buffer_pool.rs index 4a136fdf..83e42503 100644 --- a/foyer-storage/src/io_buffer_pool.rs +++ b/foyer-storage/src/io_buffer_pool.rs @@ -14,7 +14,9 @@ use std::collections::VecDeque; -use crate::{IoBuffer, IoBytes}; +use foyer_common::bits; + +use crate::{device::ALIGN, IoBuffer, IoBytes}; pub enum Buffer { IoBuffer(IoBuffer), @@ -41,6 +43,7 @@ pub struct IoBufferPool { impl IoBufferPool { pub fn new(buffer_size: usize, capacity: usize) -> Self { + bits::assert_aligned(ALIGN, buffer_size); Self { capacity, buffer_size, diff --git a/foyer-storage/src/large/batch.rs b/foyer-storage/src/large/batch.rs index ed7e771d..a4e46f87 100644 --- a/foyer-storage/src/large/batch.rs +++ b/foyer-storage/src/large/batch.rs @@ -117,6 +117,7 @@ where S: HashBuilder + Debug, { pub fn new(capacity: usize, region_manager: RegionManager, device: MonitoredDevice, indexer: Indexer) -> Self { + let capacity = bits::align_up(device.align(), capacity); let mut batch = Self { buffer: IoBuffer::new(capacity), len: 0, From a52da3a523dcaccbad30d7e513aa69d2ab3fc7d8 Mon Sep 17 00:00:00 2001 From: Croxx Date: Fri, 20 Sep 2024 13:07:40 +0800 Subject: [PATCH 37/40] chore: relase foyer 0.11.3 (#725) Signed-off-by: MrCroxx --- CHANGELOG.md | 18 +++++++++++++++++- foyer-bench/Cargo.toml | 4 ++-- foyer-common/Cargo.toml | 2 +- foyer-intrusive/Cargo.toml | 4 ++-- foyer-memory/Cargo.toml | 6 +++--- foyer-storage/Cargo.toml | 6 +++--- foyer/Cargo.toml | 8 ++++---- 7 files changed, 32 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 47a2dd24..a989f5f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,6 @@ title: Changelog description: Changelog for foyer. authors: mrcroxx -tags: [changelog] date: 2023-05-12T11:02:09+08:00 --- @@ -10,6 +9,23 @@ date: 2023-05-12T11:02:09+08:00 +## 2024-09-20 + +### Releases + +| crate | version | +| - | - | +| foyer | 0.11.3 | +| foyer-common | 0.9.3 | +| foyer-intrusive | 0.9.3 | +| foyer-memory | 0.7.3 | +| foyer-storage | 0.10.3 | +| foyer-bench | 0.3.3 | + +### Changes + +- Fix panicked by io buffer pool alignment issue. + ## 2024-09-12 ### Releases diff --git a/foyer-bench/Cargo.toml b/foyer-bench/Cargo.toml index c6bd15bc..9ca1c6bb 100644 --- a/foyer-bench/Cargo.toml +++ b/foyer-bench/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "foyer-bench" -version = "0.3.2" +version = "0.3.3" edition = "2021" authors = ["MrCroxx "] description = "bench tool for foyer - the hybrid cache for Rust" @@ -17,7 +17,7 @@ clap = { workspace = true } console-subscriber = { version = "0.4", optional = true } fastrace = { workspace = true, optional = true } fastrace-jaeger = { workspace = true, optional = true } -foyer = { version = "0.11.2", path = "../foyer" } +foyer = { version = "0.11.3", path = "../foyer" } futures = "0.3" hdrhistogram = "7" itertools = { workspace = true } diff --git a/foyer-common/Cargo.toml b/foyer-common/Cargo.toml index bd9d5f37..16ef110d 100644 --- a/foyer-common/Cargo.toml +++ b/foyer-common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "foyer-common" -version = "0.9.2" +version = "0.9.3" edition = "2021" authors = ["MrCroxx "] description = "common components for foyer - the hybrid cache for Rust" diff --git a/foyer-intrusive/Cargo.toml b/foyer-intrusive/Cargo.toml index 598e35c5..abdf950d 100644 --- a/foyer-intrusive/Cargo.toml +++ b/foyer-intrusive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "foyer-intrusive" -version = "0.9.2" +version = "0.9.3" edition = "2021" authors = ["MrCroxx "] description = "intrusive data structures for foyer - the hybrid cache for Rust" @@ -11,7 +11,7 @@ readme = "../README.md" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -foyer-common = { version = "0.9.2", path = "../foyer-common" } +foyer-common = { version = "0.9.3", path = "../foyer-common" } itertools = { workspace = true } [features] diff --git a/foyer-memory/Cargo.toml b/foyer-memory/Cargo.toml index ba2ee1c0..f971ad0e 100644 --- a/foyer-memory/Cargo.toml +++ b/foyer-memory/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "foyer-memory" -version = "0.7.2" +version = "0.7.3" edition = "2021" authors = ["MrCroxx "] description = "memory cache for foyer - the hybrid cache for Rust" @@ -15,8 +15,8 @@ ahash = "0.8" bitflags = "2" cmsketch = "0.2.1" fastrace = { workspace = true } -foyer-common = { version = "0.9.2", path = "../foyer-common" } -foyer-intrusive = { version = "0.9.2", path = "../foyer-intrusive" } +foyer-common = { version = "0.9.3", path = "../foyer-common" } +foyer-intrusive = { version = "0.9.3", path = "../foyer-intrusive" } futures = "0.3" hashbrown = "0.14" itertools = { workspace = true } diff --git a/foyer-storage/Cargo.toml b/foyer-storage/Cargo.toml index 1a2c365c..3812d80b 100644 --- a/foyer-storage/Cargo.toml +++ b/foyer-storage/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "foyer-storage" -version = "0.10.2" +version = "0.10.3" edition = "2021" authors = ["MrCroxx "] description = "storage engine for foyer - the hybrid cache for Rust" @@ -24,8 +24,8 @@ bytes = "1" clap = { workspace = true } either = "1" fastrace = { workspace = true } -foyer-common = { version = "0.9.2", path = "../foyer-common" } -foyer-memory = { version = "0.7.2", path = "../foyer-memory" } +foyer-common = { version = "0.9.3", path = "../foyer-common" } +foyer-memory = { version = "0.7.3", path = "../foyer-memory" } fs4 = "0.9.1" futures = "0.3" itertools = { workspace = true } diff --git a/foyer/Cargo.toml b/foyer/Cargo.toml index 6c925596..25a4e837 100644 --- a/foyer/Cargo.toml +++ b/foyer/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "foyer" -version = "0.11.2" +version = "0.11.3" edition = "2021" authors = ["MrCroxx "] description = "Hybrid cache for Rust" @@ -15,9 +15,9 @@ rust-version = "1.81.0" ahash = "0.8" anyhow = "1" fastrace = { workspace = true } -foyer-common = { version = "0.9.2", path = "../foyer-common" } -foyer-memory = { version = "0.7.2", path = "../foyer-memory" } -foyer-storage = { version = "0.10.2", path = "../foyer-storage" } +foyer-common = { version = "0.9.3", path = "../foyer-common" } +foyer-memory = { version = "0.7.3", path = "../foyer-memory" } +foyer-storage = { version = "0.10.3", path = "../foyer-storage" } futures = "0.3" pin-project = "1" tokio = { workspace = true } From fd68f1b33903f30f3f93d5e20708ebea70d24272 Mon Sep 17 00:00:00 2001 From: Croxx Date: Fri, 20 Sep 2024 13:48:29 +0800 Subject: [PATCH 38/40] doc: fix a tiny broken link (#728) Signed-off-by: MrCroxx --- foyer-storage/src/device/direct_file.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/foyer-storage/src/device/direct_file.rs b/foyer-storage/src/device/direct_file.rs index b56cbd59..6b66c020 100644 --- a/foyer-storage/src/device/direct_file.rs +++ b/foyer-storage/src/device/direct_file.rs @@ -251,7 +251,7 @@ impl Dev for DirectFileDevice { } } -/// [`DirectFiDeviceOptionsBuilder`] is used to build the options for the direct fs device. +/// [`DirectFileDeviceOptionsBuilder`] is used to build the options for the direct fs device. /// /// The direct fs device uses a directory in a file system to store the data of disk cache. /// From f1490da1078c54359ee7896a607a245cf08bb9ff Mon Sep 17 00:00:00 2001 From: Croxx Date: Fri, 20 Sep 2024 15:18:11 +0800 Subject: [PATCH 39/40] refactor: rename with_buffer_threshold to with_buffer_pool_size (#729) Signed-off-by: MrCroxx --- examples/hybrid_full.rs | 2 +- foyer-storage/src/store.rs | 28 ++++++++++++++++++++++------ foyer/src/hybrid/builder.rs | 24 +++++++++++++++++++++++- 3 files changed, 46 insertions(+), 8 deletions(-) diff --git a/examples/hybrid_full.rs b/examples/hybrid_full.rs index 14ca0ff1..97f98500 100644 --- a/examples/hybrid_full.rs +++ b/examples/hybrid_full.rs @@ -48,7 +48,7 @@ async fn main() -> Result<()> { .with_recover_concurrency(8) .with_flushers(2) .with_reclaimers(2) - .with_buffer_threshold(256 * 1024 * 1024) + .with_buffer_pool_size(256 * 1024 * 1024) .with_clean_region_threshold(4) .with_eviction_pickers(vec![Box::::default()]) .with_admission_picker(Arc::new(RateLimitPicker::new(100 * 1024 * 1024))) diff --git a/foyer-storage/src/store.rs b/foyer-storage/src/store.rs index 5ed47948..663f9870 100644 --- a/foyer-storage/src/store.rs +++ b/foyer-storage/src/store.rs @@ -357,8 +357,7 @@ where recover_concurrency: usize, flushers: usize, reclaimers: usize, - // FIXME(MrCroxx): rename the field and builder fn. - buffer_threshold: usize, + buffer_pool_size: usize, clean_region_threshold: Option, eviction_pickers: Vec>, admission_picker: Arc>, @@ -387,7 +386,7 @@ where recover_concurrency: 8, flushers: 1, reclaimers: 1, - buffer_threshold: 16 * 1024 * 1024, // 16 MiB + buffer_pool_size: 16 * 1024 * 1024, // 16 MiB clean_region_threshold: None, eviction_pickers: vec![Box::new(InvalidRatioPicker::new(0.8)), Box::::default()], admission_picker: Arc::>::default(), @@ -469,6 +468,7 @@ where self } + // FIXME(MrCroxx): remove it after 0.12 /// Set the total flush buffer threshold. /// /// Each flusher shares a volume at `threshold / flushers`. @@ -476,8 +476,24 @@ where /// If the buffer of the flush queue exceeds the threshold, the further entries will be ignored. /// /// Default: 16 MiB. + #[deprecated( + since = "0.11.4", + note = "The function will be renamed to \"with_buffer_pool_size()\", use it instead." + )] pub fn with_buffer_threshold(mut self, threshold: usize) -> Self { - self.buffer_threshold = threshold; + self.buffer_pool_size = threshold; + self + } + + /// Set the total flush buffer pool size. + /// + /// Each flusher shares a volume at `threshold / flushers`. + /// + /// If the buffer of the flush queue exceeds the threshold, the further entries will be ignored. + /// + /// Default: 16 MiB. + pub fn with_buffer_pool_size(mut self, buffer_pool_size: usize) -> Self { + self.buffer_pool_size = buffer_pool_size; self } @@ -659,7 +675,7 @@ where eviction_pickers: self.eviction_pickers, reinsertion_picker: self.reinsertion_picker, tombstone_log_config: self.tombstone_log_config, - buffer_threshold: self.buffer_threshold, + buffer_threshold: self.buffer_pool_size, statistics: statistics.clone(), write_runtime_handle, read_runtime_handle, @@ -702,7 +718,7 @@ where eviction_pickers: self.eviction_pickers, reinsertion_picker: self.reinsertion_picker, tombstone_log_config: self.tombstone_log_config, - buffer_threshold: self.buffer_threshold, + buffer_threshold: self.buffer_pool_size, statistics: statistics.clone(), write_runtime_handle, read_runtime_handle, diff --git a/foyer/src/hybrid/builder.rs b/foyer/src/hybrid/builder.rs index 3ee2a450..34eb69be 100644 --- a/foyer/src/hybrid/builder.rs +++ b/foyer/src/hybrid/builder.rs @@ -299,6 +299,7 @@ where } } + // FIXME(MrCroxx): remove it after 0.12 /// Set the total flush buffer threshold. /// /// Each flusher shares a volume at `threshold / flushers`. @@ -306,8 +307,29 @@ where /// If the buffer of the flush queue exceeds the threshold, the further entries will be ignored. /// /// Default: 16 MiB. + #[deprecated( + since = "0.11.4", + note = "The function will be renamed to \"with_buffer_pool_size()\", use it instead." + )] pub fn with_buffer_threshold(self, threshold: usize) -> Self { - let builder = self.builder.with_buffer_threshold(threshold); + let builder = self.builder.with_buffer_pool_size(threshold); + Self { + name: self.name, + tracing_config: self.tracing_config, + memory: self.memory, + builder, + } + } + + /// Set the total flush buffer pool size. + /// + /// Each flusher shares a volume at `threshold / flushers`. + /// + /// If the buffer of the flush queue exceeds the threshold, the further entries will be ignored. + /// + /// Default: 16 MiB. + pub fn with_buffer_pool_size(self, buffer_pool_size: usize) -> Self { + let builder = self.builder.with_buffer_pool_size(buffer_pool_size); Self { name: self.name, tracing_config: self.tracing_config, From 553a9cbdd8a392d1aa071eeb9c00b49555f60162 Mon Sep 17 00:00:00 2001 From: Croxx Date: Fri, 20 Sep 2024 15:59:28 +0800 Subject: [PATCH 40/40] chore: warn if DirectFileDevice is used in a fs (#730) Signed-off-by: MrCroxx --- foyer-storage/src/device/direct_file.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/foyer-storage/src/device/direct_file.rs b/foyer-storage/src/device/direct_file.rs index 6b66c020..6b8170f3 100644 --- a/foyer-storage/src/device/direct_file.rs +++ b/foyer-storage/src/device/direct_file.rs @@ -199,6 +199,12 @@ impl Dev for DirectFileDevice { let file = opts.open(&options.path)?; if file.metadata().unwrap().is_file() { + tracing::warn!( + "{}\n{}\n{}", + "It seems a `DirectFileDevice` is used within a normal file system, which is inefficient.", + "Please use `DirectFileDevice` directly on a raw block device.", + "Or use `DirectFsDevice` within a normal file system.", + ); file.set_len(options.capacity as _)?; }