mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-17 18:27:49 +00:00
feat(admin): expose global heal progress (#3897)
This commit is contained in:
@@ -1916,6 +1916,23 @@ impl HealManager {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn active_progress_snapshot(&self) -> Option<HealProgress> {
|
||||
let active_heals = self.active_heals.lock().await;
|
||||
if active_heals.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut snapshot = HealProgress::default();
|
||||
for task in active_heals.values() {
|
||||
let progress = task.get_progress().await;
|
||||
snapshot.objects_scanned = snapshot.objects_scanned.saturating_add(progress.objects_scanned);
|
||||
snapshot.objects_healed = snapshot.objects_healed.saturating_add(progress.objects_healed);
|
||||
snapshot.objects_failed = snapshot.objects_failed.saturating_add(progress.objects_failed);
|
||||
snapshot.bytes_processed = snapshot.bytes_processed.saturating_add(progress.bytes_processed);
|
||||
}
|
||||
Some(snapshot)
|
||||
}
|
||||
|
||||
/// Start scheduler
|
||||
async fn start_scheduler(&self) -> Result<()> {
|
||||
let config = self.config.clone();
|
||||
@@ -3796,6 +3813,43 @@ mod tests {
|
||||
assert_eq!(snapshot.active_by_source.scanner, 0);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_active_progress_snapshot_sums_active_task_progress() {
|
||||
let storage: Arc<dyn HealStorageAPI> = Arc::new(MockStorage);
|
||||
let manager = HealManager::new(storage, None);
|
||||
|
||||
let first = Arc::new(HealTask::from_request(
|
||||
HealRequest::bucket("bucket-a".to_string()),
|
||||
manager.storage.clone(),
|
||||
));
|
||||
{
|
||||
let mut progress = first.progress.write().await;
|
||||
progress.update_progress(7, 3, 1, 4096);
|
||||
}
|
||||
|
||||
let second = Arc::new(HealTask::from_request(
|
||||
HealRequest::bucket("bucket-b".to_string()),
|
||||
manager.storage.clone(),
|
||||
));
|
||||
{
|
||||
let mut progress = second.progress.write().await;
|
||||
progress.update_progress(11, 5, 2, 2048);
|
||||
}
|
||||
|
||||
manager.active_heals.lock().await.insert(first.id.clone(), first);
|
||||
manager.active_heals.lock().await.insert(second.id.clone(), second);
|
||||
|
||||
let progress = manager
|
||||
.active_progress_snapshot()
|
||||
.await
|
||||
.expect("active progress should exist");
|
||||
|
||||
assert_eq!(progress.objects_scanned, 18);
|
||||
assert_eq!(progress.objects_healed, 8);
|
||||
assert_eq!(progress.objects_failed, 3);
|
||||
assert_eq!(progress.bytes_processed, 6144);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_get_task_status_for_path_rejects_wrong_token_when_path_is_active() {
|
||||
let storage: Arc<dyn HealStorageAPI> = Arc::new(MockStorage);
|
||||
|
||||
@@ -18,7 +18,7 @@ pub mod heal;
|
||||
pub use error::{Error, Result};
|
||||
pub use heal::{
|
||||
HealManager, HealOperationsSnapshot, HealOptions, HealPriority, HealPriorityCounts, HealRequest, HealSourceCounts, HealType,
|
||||
channel::HealChannelProcessor,
|
||||
channel::HealChannelProcessor, progress::HealProgress,
|
||||
};
|
||||
use rustfs_concurrency::WorkloadAdmissionSnapshotProvider;
|
||||
use std::sync::atomic::{AtomicU64, Ordering};
|
||||
@@ -163,6 +163,14 @@ pub async fn current_heal_operations_snapshot() -> HealOperationsSnapshot {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn current_heal_progress_snapshot() -> Option<HealProgress> {
|
||||
if let Some(manager) = get_heal_manager() {
|
||||
manager.active_progress_snapshot().await
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn usize_to_u64_saturated(value: usize) -> u64 {
|
||||
u64::try_from(value).unwrap_or(u64::MAX)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user