mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-05 21:07:43 +00:00
fix rebalance/decom
This commit is contained in:
@@ -34,9 +34,9 @@ pub struct RebalPoolProgress {
|
||||
#[serde(rename = "object")]
|
||||
pub object: String,
|
||||
#[serde(rename = "elapsed")]
|
||||
pub elapsed: Duration,
|
||||
pub elapsed: u64,
|
||||
#[serde(rename = "eta")]
|
||||
pub eta: Duration,
|
||||
pub eta: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||
@@ -78,13 +78,13 @@ impl Operation for RebalanceStart {
|
||||
|
||||
if store.is_decommission_running().await {
|
||||
return Err(s3_error!(
|
||||
InternalError,
|
||||
InvalidRequest,
|
||||
"Rebalance cannot be started, decommission is already in progress"
|
||||
));
|
||||
}
|
||||
|
||||
if store.is_rebalance_started().await {
|
||||
return Err(s3_error!(InternalError, "Rebalance already in progress"));
|
||||
return Err(s3_error!(OperationAborted, "Rebalance already in progress"));
|
||||
}
|
||||
|
||||
let bucket_infos = store
|
||||
@@ -101,8 +101,11 @@ impl Operation for RebalanceStart {
|
||||
}
|
||||
};
|
||||
|
||||
warn!("Rebalance started with id: {}", id);
|
||||
if let Some(notification_sys) = get_global_notification_sys() {
|
||||
warn!("Loading rebalance meta");
|
||||
notification_sys.load_rebalance_meta(true).await;
|
||||
warn!("Rebalance meta loaded");
|
||||
}
|
||||
|
||||
let resp = RebalanceResp { id };
|
||||
@@ -149,7 +152,7 @@ impl Operation for RebalanceStatus {
|
||||
disk_stats[disk.pool_index as usize].total_space += disk.total_space;
|
||||
}
|
||||
|
||||
let stop_time = meta.stopped_at;
|
||||
let mut stop_time = meta.stopped_at;
|
||||
let mut admin_status = RebalanceAdminStatus {
|
||||
id: meta.id.clone(),
|
||||
stopped_at: meta.stopped_at,
|
||||
@@ -171,7 +174,7 @@ impl Operation for RebalanceStatus {
|
||||
// Calculate total bytes to be rebalanced
|
||||
let total_bytes_to_rebal = ps.init_capacity as f64 * meta.percent_free_goal - ps.init_free_space as f64;
|
||||
|
||||
let elapsed = if let Some(start_time) = ps.info.start_time {
|
||||
let mut elapsed = if let Some(start_time) = ps.info.start_time {
|
||||
SystemTime::now()
|
||||
.duration_since(start_time)
|
||||
.map_err(|e| s3_error!(InternalError, "Failed to calculate elapsed time: {}", e))?
|
||||
@@ -179,21 +182,25 @@ impl Operation for RebalanceStatus {
|
||||
return Err(s3_error!(InternalError, "Start time is not available"));
|
||||
};
|
||||
|
||||
let eta = if ps.bytes > 0 {
|
||||
let mut eta = if ps.bytes > 0 {
|
||||
Duration::from_secs_f64(total_bytes_to_rebal * elapsed.as_secs_f64() / ps.bytes as f64)
|
||||
} else {
|
||||
Duration::ZERO
|
||||
};
|
||||
|
||||
let stop_time = ps.info.end_time.unwrap_or(stop_time.unwrap_or(SystemTime::now()));
|
||||
if ps.info.end_time.is_some() {
|
||||
stop_time = ps.info.end_time;
|
||||
}
|
||||
|
||||
let elapsed = if ps.info.end_time.is_some() || meta.stopped_at.is_some() {
|
||||
stop_time
|
||||
.duration_since(ps.info.start_time.unwrap_or(stop_time))
|
||||
.unwrap_or_default()
|
||||
} else {
|
||||
elapsed
|
||||
};
|
||||
if let Some(stopped_at) = stop_time {
|
||||
if let Ok(du) = stopped_at.duration_since(ps.info.start_time.unwrap_or(stopped_at)) {
|
||||
elapsed = du;
|
||||
} else {
|
||||
return Err(s3_error!(InternalError, "Failed to calculate elapsed time"));
|
||||
}
|
||||
|
||||
eta = Duration::ZERO;
|
||||
}
|
||||
|
||||
admin_status.pools[i].progress = Some(RebalPoolProgress {
|
||||
num_objects: ps.num_objects,
|
||||
@@ -201,8 +208,8 @@ impl Operation for RebalanceStatus {
|
||||
bytes: ps.bytes,
|
||||
bucket: ps.bucket.clone(),
|
||||
object: ps.object.clone(),
|
||||
elapsed,
|
||||
eta,
|
||||
elapsed: elapsed.as_secs(),
|
||||
eta: eta.as_secs(),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+10
-2
@@ -40,7 +40,7 @@ use tokio::spawn;
|
||||
use tokio::sync::mpsc;
|
||||
use tokio_stream::wrappers::ReceiverStream;
|
||||
use tonic::{Request, Response, Status, Streaming};
|
||||
use tracing::{debug, error, info};
|
||||
use tracing::{debug, error, info, warn};
|
||||
|
||||
type ResponseStream<T> = Pin<Box<dyn Stream<Item = Result<T, tonic::Status>> + Send>>;
|
||||
|
||||
@@ -2388,19 +2388,27 @@ impl Node for NodeService {
|
||||
|
||||
let LoadRebalanceMetaRequest { start_rebalance } = request.into_inner();
|
||||
|
||||
warn!("handle LoadRebalanceMetaRequest");
|
||||
|
||||
store.load_rebalance_meta().await.map_err(|err| {
|
||||
error!("load_rebalance_meta err {:?}", err);
|
||||
Status::internal(err.to_string())
|
||||
})?;
|
||||
|
||||
warn!("load_rebalance_meta success");
|
||||
|
||||
if start_rebalance {
|
||||
warn!("start rebalance");
|
||||
let store = store.clone();
|
||||
tokio::spawn(async move {
|
||||
store.start_rebalance().await;
|
||||
});
|
||||
}
|
||||
|
||||
unimplemented!()
|
||||
Ok(tonic::Response::new(LoadRebalanceMetaResponse {
|
||||
success: true,
|
||||
error_info: None,
|
||||
}))
|
||||
}
|
||||
|
||||
async fn load_transition_tier_config(
|
||||
|
||||
Reference in New Issue
Block a user