mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-24 11:21:08 +00:00
chore(storage-monitor): improve free_space calculation and cli default value (#14133)
* chore(storage-monitor): fix free_space calculation * add `Result` type * add docs * update `polling_period` default value to `6` * Update client/storage-monitor/src/lib.rs Co-authored-by: Michal Kucharczyk <1728078+michalkucharczyk@users.noreply.github.com> * Apply suggestions from code review --------- Co-authored-by: Michal Kucharczyk <1728078+michalkucharczyk@users.noreply.github.com> Co-authored-by: Bastian Köcher <git@kchr.de>
This commit is contained in:
@@ -27,12 +27,15 @@ use std::{
|
|||||||
|
|
||||||
const LOG_TARGET: &str = "storage-monitor";
|
const LOG_TARGET: &str = "storage-monitor";
|
||||||
|
|
||||||
|
/// Result type used in this crate.
|
||||||
|
pub type Result<T> = std::result::Result<T, Error>;
|
||||||
|
|
||||||
/// Error type used in this crate.
|
/// Error type used in this crate.
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
#[error("IO Error")]
|
#[error("IO Error")]
|
||||||
IOError(#[from] io::Error),
|
IOError(#[from] io::Error),
|
||||||
#[error("Out of storage space: available {0}MB, required {1}MB")]
|
#[error("Out of storage space: available {0}MiB, required {1}MiB")]
|
||||||
StorageOutOfSpace(u64, u64),
|
StorageOutOfSpace(u64, u64),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,7 +45,7 @@ pub struct StorageMonitorParams {
|
|||||||
/// Required available space on database storage. If available space for DB storage drops below
|
/// Required available space on database storage. If available space for DB storage drops below
|
||||||
/// the given threshold, node will be gracefully terminated. If `0` is given monitoring will be
|
/// the given threshold, node will be gracefully terminated. If `0` is given monitoring will be
|
||||||
/// disabled.
|
/// disabled.
|
||||||
#[arg(long = "db-storage-threshold", value_name = "MB", default_value_t = 1000)]
|
#[arg(long = "db-storage-threshold", value_name = "MiB", default_value_t = 1024)]
|
||||||
pub threshold: u64,
|
pub threshold: u64,
|
||||||
|
|
||||||
/// How often available space is polled.
|
/// How often available space is polled.
|
||||||
@@ -50,14 +53,14 @@ pub struct StorageMonitorParams {
|
|||||||
pub polling_period: u32,
|
pub polling_period: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Storage monitor service: checks the available space for the filesystem for fiven path.
|
/// Storage monitor service: checks the available space for the filesystem for given path.
|
||||||
pub struct StorageMonitorService {
|
pub struct StorageMonitorService {
|
||||||
/// watched path
|
/// watched path
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
/// number of megabytes that shall be free on the filesystem for watched path
|
/// number of megabytes that shall be free on the filesystem for watched path
|
||||||
threshold: u64,
|
threshold: u64,
|
||||||
/// storage space polling period (seconds)
|
/// storage space polling period
|
||||||
polling_period: u32,
|
polling_period: Duration,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StorageMonitorService {
|
impl StorageMonitorService {
|
||||||
@@ -66,7 +69,7 @@ impl StorageMonitorService {
|
|||||||
parameters: StorageMonitorParams,
|
parameters: StorageMonitorParams,
|
||||||
database: DatabaseSource,
|
database: DatabaseSource,
|
||||||
spawner: &impl SpawnEssentialNamed,
|
spawner: &impl SpawnEssentialNamed,
|
||||||
) -> Result<(), Error> {
|
) -> Result<()> {
|
||||||
Ok(match (parameters.threshold, database.path()) {
|
Ok(match (parameters.threshold, database.path()) {
|
||||||
(0, _) => {
|
(0, _) => {
|
||||||
log::info!(
|
log::info!(
|
||||||
@@ -83,8 +86,7 @@ impl StorageMonitorService {
|
|||||||
(threshold, Some(path)) => {
|
(threshold, Some(path)) => {
|
||||||
log::debug!(
|
log::debug!(
|
||||||
target: LOG_TARGET,
|
target: LOG_TARGET,
|
||||||
"Initializing StorageMonitorService for db path: {:?}",
|
"Initializing StorageMonitorService for db path: {path:?}",
|
||||||
path,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Self::check_free_space(&path, threshold)?;
|
Self::check_free_space(&path, threshold)?;
|
||||||
@@ -92,7 +94,7 @@ impl StorageMonitorService {
|
|||||||
let storage_monitor_service = StorageMonitorService {
|
let storage_monitor_service = StorageMonitorService {
|
||||||
path: path.to_path_buf(),
|
path: path.to_path_buf(),
|
||||||
threshold,
|
threshold,
|
||||||
polling_period: parameters.polling_period,
|
polling_period: Duration::from_secs(parameters.polling_period.into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
spawner.spawn_essential(
|
spawner.spawn_essential(
|
||||||
@@ -108,22 +110,22 @@ impl StorageMonitorService {
|
|||||||
/// below threshold.
|
/// below threshold.
|
||||||
async fn run(self) {
|
async fn run(self) {
|
||||||
loop {
|
loop {
|
||||||
tokio::time::sleep(Duration::from_secs(self.polling_period.into())).await;
|
tokio::time::sleep(self.polling_period).await;
|
||||||
if Self::check_free_space(&self.path, self.threshold).is_err() {
|
if Self::check_free_space(&self.path, self.threshold).is_err() {
|
||||||
break
|
break
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns free space in MB, or error if statvfs failed.
|
/// Returns free space in MiB, or error if statvfs failed.
|
||||||
fn free_space(path: &Path) -> Result<u64, Error> {
|
fn free_space(path: &Path) -> Result<u64> {
|
||||||
Ok(fs4::available_space(path).map(|s| s / 1_000_000)?)
|
Ok(fs4::available_space(path).map(|s| s / 1024 / 1024)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if the amount of free space for given `path` is above given `threshold`.
|
/// Checks if the amount of free space for given `path` is above given `threshold` in MiB.
|
||||||
/// If it dropped below, error is returned.
|
/// If it dropped below, error is returned.
|
||||||
/// System errors are silently ignored.
|
/// System errors are silently ignored.
|
||||||
fn check_free_space(path: &Path, threshold: u64) -> Result<(), Error> {
|
fn check_free_space(path: &Path, threshold: u64) -> Result<()> {
|
||||||
match StorageMonitorService::free_space(path) {
|
match StorageMonitorService::free_space(path) {
|
||||||
Ok(available_space) => {
|
Ok(available_space) => {
|
||||||
log::trace!(
|
log::trace!(
|
||||||
@@ -132,14 +134,14 @@ impl StorageMonitorService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if available_space < threshold {
|
if available_space < threshold {
|
||||||
log::error!(target: LOG_TARGET, "Available space {available_space}MB for path `{}` dropped below threshold: {threshold}MB , terminating...", path.display());
|
log::error!(target: LOG_TARGET, "Available space {available_space}MiB for path `{}` dropped below threshold: {threshold}MiB , terminating...", path.display());
|
||||||
Err(Error::StorageOutOfSpace(available_space, threshold))
|
Err(Error::StorageOutOfSpace(available_space, threshold))
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!(target: LOG_TARGET, "Could not read available space: {:?}.", e);
|
log::error!(target: LOG_TARGET, "Could not read available space: {e:?}.");
|
||||||
Err(e)
|
Err(e)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user