mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-19 19:16:17 +00:00
Centralize lifecycle state updates and fix systemd running status (#2567)
This commit is contained in:
@@ -673,7 +673,7 @@ impl DataUsageCache {
|
||||
let mut leaves = Vec::new();
|
||||
let mut remove = total - limit;
|
||||
add(self, path, &mut leaves);
|
||||
leaves.sort_by(|a, b| a.objects.cmp(&b.objects));
|
||||
leaves.sort_by_key(|a| a.objects);
|
||||
|
||||
while remove > 0 && !leaves.is_empty() {
|
||||
let Some(e) = leaves.first() else {
|
||||
|
||||
@@ -101,11 +101,7 @@ impl InternodeMetrics {
|
||||
pub fn snapshot(&self) -> InternodeMetricsSnapshot {
|
||||
let dial_samples_total = self.dial_samples_total.load(Ordering::Relaxed);
|
||||
let dial_total_time_nanos = self.dial_total_time_nanos.load(Ordering::Relaxed);
|
||||
let dial_avg_time_nanos = if dial_samples_total == 0 {
|
||||
0
|
||||
} else {
|
||||
dial_total_time_nanos / dial_samples_total
|
||||
};
|
||||
let dial_avg_time_nanos = dial_total_time_nanos.checked_div(dial_samples_total).unwrap_or(0);
|
||||
|
||||
InternodeMetricsSnapshot {
|
||||
sent_bytes_total: self.sent_bytes_total.load(Ordering::Relaxed),
|
||||
|
||||
@@ -41,7 +41,6 @@ serde_json.workspace = true
|
||||
tonic = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
tokio-stream = { workspace = true }
|
||||
clap = { workspace = true }
|
||||
rustfs-madmin.workspace = true
|
||||
rustfs-filemeta.workspace = true
|
||||
bytes.workspace = true
|
||||
@@ -53,8 +52,6 @@ async-compression = { workspace = true, features = ["tokio", "bzip2", "xz"] }
|
||||
async-trait = { workspace = true }
|
||||
flate2.workspace = true
|
||||
http.workspace = true
|
||||
http-body.workspace = true
|
||||
http-body-util.workspace = true
|
||||
reqwest = { workspace = true }
|
||||
rustfs-signer.workspace = true
|
||||
tracing = { workspace = true }
|
||||
|
||||
@@ -1687,10 +1687,8 @@ pub async fn eval_action_from_lifecycle(
|
||||
let lock_enabled = if let Some(lr) = lr { lr.mode.is_some() } else { false };
|
||||
|
||||
match event.action {
|
||||
IlmAction::DeleteAllVersionsAction | IlmAction::DelMarkerDeleteAllVersionsAction => {
|
||||
if lock_enabled {
|
||||
return lifecycle::Event::default();
|
||||
}
|
||||
IlmAction::DeleteAllVersionsAction | IlmAction::DelMarkerDeleteAllVersionsAction if lock_enabled => {
|
||||
return lifecycle::Event::default();
|
||||
}
|
||||
IlmAction::DeleteVersionAction | IlmAction::DeleteRestoredVersionAction => {
|
||||
if oi.version_id.is_none() {
|
||||
|
||||
@@ -832,61 +832,55 @@ impl ReplicationStats {
|
||||
let mut rs = ReplStat::new();
|
||||
|
||||
match status {
|
||||
ReplicationStatusType::Pending => {
|
||||
if ri.op_type.is_data_replication() && prev_status != status {
|
||||
rs.set(
|
||||
ri.arn.clone(),
|
||||
ri.size,
|
||||
Duration::default(),
|
||||
status,
|
||||
ri.op_type,
|
||||
ri.endpoint.clone(),
|
||||
ri.secure,
|
||||
ri.error.as_ref().map(|e| crate::error::Error::other(e.clone())),
|
||||
);
|
||||
}
|
||||
ReplicationStatusType::Pending if ri.op_type.is_data_replication() && prev_status != status => {
|
||||
rs.set(
|
||||
ri.arn.clone(),
|
||||
ri.size,
|
||||
Duration::default(),
|
||||
status,
|
||||
ri.op_type,
|
||||
ri.endpoint.clone(),
|
||||
ri.secure,
|
||||
ri.error.as_ref().map(|e| crate::error::Error::other(e.clone())),
|
||||
);
|
||||
}
|
||||
ReplicationStatusType::Completed => {
|
||||
if ri.op_type.is_data_replication() {
|
||||
rs.set(
|
||||
ri.arn.clone(),
|
||||
ri.size,
|
||||
ri.duration,
|
||||
status,
|
||||
ri.op_type,
|
||||
ri.endpoint.clone(),
|
||||
ri.secure,
|
||||
ri.error.as_ref().map(|e| crate::error::Error::other(e.clone())),
|
||||
);
|
||||
}
|
||||
ReplicationStatusType::Completed if ri.op_type.is_data_replication() => {
|
||||
rs.set(
|
||||
ri.arn.clone(),
|
||||
ri.size,
|
||||
ri.duration,
|
||||
status,
|
||||
ri.op_type,
|
||||
ri.endpoint.clone(),
|
||||
ri.secure,
|
||||
ri.error.as_ref().map(|e| crate::error::Error::other(e.clone())),
|
||||
);
|
||||
}
|
||||
ReplicationStatusType::Failed => {
|
||||
if ri.op_type.is_data_replication() && prev_status == ReplicationStatusType::Pending {
|
||||
rs.set(
|
||||
ri.arn.clone(),
|
||||
ri.size,
|
||||
ri.duration,
|
||||
status,
|
||||
ri.op_type,
|
||||
ri.endpoint.clone(),
|
||||
ri.secure,
|
||||
ri.error.as_ref().map(|e| crate::error::Error::other(e.clone())),
|
||||
);
|
||||
}
|
||||
ReplicationStatusType::Failed
|
||||
if ri.op_type.is_data_replication() && prev_status == ReplicationStatusType::Pending =>
|
||||
{
|
||||
rs.set(
|
||||
ri.arn.clone(),
|
||||
ri.size,
|
||||
ri.duration,
|
||||
status,
|
||||
ri.op_type,
|
||||
ri.endpoint.clone(),
|
||||
ri.secure,
|
||||
ri.error.as_ref().map(|e| crate::error::Error::other(e.clone())),
|
||||
);
|
||||
}
|
||||
ReplicationStatusType::Replica => {
|
||||
if ri.op_type == ReplicationType::Object {
|
||||
rs.set(
|
||||
ri.arn.clone(),
|
||||
ri.size,
|
||||
Duration::default(),
|
||||
status,
|
||||
ri.op_type,
|
||||
String::new(),
|
||||
false,
|
||||
ri.error.as_ref().map(|e| crate::error::Error::other(e.clone())),
|
||||
);
|
||||
}
|
||||
ReplicationStatusType::Replica if ri.op_type == ReplicationType::Object => {
|
||||
rs.set(
|
||||
ri.arn.clone(),
|
||||
ri.size,
|
||||
Duration::default(),
|
||||
status,
|
||||
ri.op_type,
|
||||
String::new(),
|
||||
false,
|
||||
ri.error.as_ref().map(|e| crate::error::Error::other(e.clone())),
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
@@ -537,7 +537,7 @@ fn build_oidc_object(cfg: &Config) -> Map<String, Value> {
|
||||
};
|
||||
|
||||
let mut providers = subsystem.iter().collect::<Vec<_>>();
|
||||
providers.sort_by(|(lhs, _), (rhs, _)| lhs.cmp(rhs));
|
||||
providers.sort_by_key(|(lhs, _)| *lhs);
|
||||
|
||||
let mut oidc_obj = Map::new();
|
||||
for (instance_key, kvs) in providers {
|
||||
@@ -572,7 +572,7 @@ fn build_semantic_oidc_object(cfg: &Config) -> Map<String, Value> {
|
||||
};
|
||||
|
||||
let mut providers = subsystem.iter().collect::<Vec<_>>();
|
||||
providers.sort_by(|(lhs, _), (rhs, _)| lhs.cmp(rhs));
|
||||
providers.sort_by_key(|(lhs, _)| *lhs);
|
||||
|
||||
let mut oidc_obj = Map::new();
|
||||
for (instance_key, kvs) in providers {
|
||||
@@ -691,7 +691,7 @@ fn build_notify_subsystem_object(
|
||||
.iter()
|
||||
.filter(|(instance_key, _)| instance_key.as_str() != DEFAULT_DELIMITER)
|
||||
.collect::<Vec<_>>();
|
||||
instances.sort_by(|(lhs, _), (rhs, _)| lhs.cmp(rhs));
|
||||
instances.sort_by_key(|(lhs, _)| *lhs);
|
||||
|
||||
for (instance_key, kvs) in instances {
|
||||
let instance_obj = build_notify_instance_diff_object(kvs, &effective_default, valid_keys, default_kvs);
|
||||
|
||||
@@ -1405,7 +1405,8 @@ impl ECStore {
|
||||
|
||||
let mut fivs = load_decommission_entry_versions(&entry, &bucket, "file_info_versions")?;
|
||||
|
||||
fivs.versions.sort_by(|a, b| b.mod_time.cmp(&a.mod_time));
|
||||
fivs.versions
|
||||
.sort_by_key(|v| (v.mod_time.is_none(), std::cmp::Reverse(v.mod_time)));
|
||||
|
||||
let mut decommissioned: usize = 0;
|
||||
let mut expired: usize = 0;
|
||||
|
||||
@@ -1530,7 +1530,8 @@ impl ECStore {
|
||||
let mut fivs =
|
||||
resolve_rebalance_file_info_versions_result(entry.file_info_versions(&bucket), bucket.as_str(), entry.name.as_str())?;
|
||||
|
||||
fivs.versions.sort_by(|a, b| b.mod_time.cmp(&a.mod_time));
|
||||
fivs.versions
|
||||
.sort_by_key(|v| (v.mod_time.is_none(), std::cmp::Reverse(v.mod_time)));
|
||||
|
||||
let mut rebalanced: usize = 0;
|
||||
let mut expired: usize = 0;
|
||||
|
||||
@@ -1627,7 +1627,7 @@ impl ObjectOperations for SetDisks {
|
||||
let mut vers = Vec::with_capacity(vers_map.len());
|
||||
|
||||
for (_, mut fi_vers) in vers_map {
|
||||
fi_vers.versions.sort_by(|a, b| a.deleted.cmp(&b.deleted));
|
||||
fi_vers.versions.sort_by_key(|a| a.deleted);
|
||||
|
||||
if let Some(index) = fi_vers.versions.iter().position(|fi| fi.deleted) {
|
||||
fi_vers.versions.truncate(index + 1);
|
||||
@@ -2961,7 +2961,7 @@ impl MultipartOperations for SetDisks {
|
||||
populated_upload_ids.insert(upload_id);
|
||||
}
|
||||
|
||||
uploads.sort_by(|a, b| a.initiated.cmp(&b.initiated));
|
||||
uploads.sort_by_key(|a| a.initiated);
|
||||
|
||||
let mut upload_idx = 0;
|
||||
if let Some(upload_id_marker) = &upload_id_marker {
|
||||
@@ -4212,7 +4212,7 @@ async fn get_storage_info(disks: &[Option<DiskStore>], eps: &[Endpoint]) -> rust
|
||||
// },
|
||||
// }
|
||||
let mut disks = get_disks_info(disks, eps).await;
|
||||
disks.sort_by(|a, b| a.total_space.cmp(&b.total_space));
|
||||
disks.sort_by_key(|a| a.total_space);
|
||||
|
||||
// Provide minimal backend shape for callers. Do NOT guess parity here since it belongs to higher-level config.
|
||||
// Missing/empty standard_sc_data will be handled by capacity fallback logic.
|
||||
|
||||
@@ -168,7 +168,7 @@ impl SetDisks {
|
||||
let mut new_disks = Vec::new();
|
||||
let mut new_infos = Vec::new();
|
||||
|
||||
for (disk, info) in disks.into_iter().zip(infos.into_iter()) {
|
||||
for (disk, info) in disks.into_iter().zip(infos) {
|
||||
let Some(info) = info else {
|
||||
continue;
|
||||
};
|
||||
|
||||
@@ -162,10 +162,8 @@ impl ListPathOptions {
|
||||
}
|
||||
|
||||
match kv[0] {
|
||||
"rustfs_cache" => {
|
||||
if kv[1] != MARKER_TAG_VERSION {
|
||||
continue;
|
||||
}
|
||||
"rustfs_cache" if kv[1] != MARKER_TAG_VERSION => {
|
||||
continue;
|
||||
}
|
||||
"id" => self.id = Some(kv[1].to_owned()),
|
||||
"return" => {
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
// Copyright 2024 RustFS Team
|
||||
//
|
||||
// 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 rustfs_filemeta::FileMeta;
|
||||
use std::{env, fs, path::PathBuf};
|
||||
|
||||
|
||||
@@ -349,7 +349,7 @@ impl FileInfo {
|
||||
|
||||
self.parts.push(part);
|
||||
|
||||
self.parts.sort_by(|a, b| a.number.cmp(&b.number));
|
||||
self.parts.sort_by_key(|a| a.number);
|
||||
}
|
||||
|
||||
// to_part_offset gets the part index where offset is located, returns part index and offset
|
||||
@@ -643,13 +643,11 @@ pub fn parse_restore_obj_status(restore_hdr: &str) -> Result<RestoreStatus> {
|
||||
}
|
||||
|
||||
match progress_tokens[1] {
|
||||
"true" | "\"true\"" => {
|
||||
if tokens.len() == 1 {
|
||||
return Ok(RestoreStatus {
|
||||
is_restore_in_progress: Some(true),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
"true" | "\"true\"" if tokens.len() == 1 => {
|
||||
return Ok(RestoreStatus {
|
||||
is_restore_in_progress: Some(true),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
"false" | "\"false\"" => {
|
||||
if tokens.len() != 2 {
|
||||
|
||||
@@ -104,7 +104,8 @@ pub fn create_real_xlmeta() -> Result<Vec<u8>> {
|
||||
fm.versions.push(legacy_shallow);
|
||||
|
||||
// Sort by modification time (newest first)
|
||||
fm.versions.sort_by(|a, b| b.header.mod_time.cmp(&a.header.mod_time));
|
||||
fm.versions
|
||||
.sort_by_key(|v| (v.header.mod_time.is_none(), std::cmp::Reverse(v.header.mod_time)));
|
||||
|
||||
fm.marshal_msg()
|
||||
}
|
||||
@@ -263,11 +264,11 @@ pub fn create_legacy_v1_object_xlmeta() -> Result<Vec<u8>> {
|
||||
wr.extend_from_slice(&[0xc6, 0, 0, 0, 0]);
|
||||
|
||||
let offset = wr.len();
|
||||
rmp::encode::write_uint(&mut wr, 1).unwrap();
|
||||
rmp::encode::write_uint(&mut wr, 1).unwrap();
|
||||
rmp::encode::write_sint(&mut wr, 1).unwrap();
|
||||
rmp::encode::write_bin(&mut wr, &header).unwrap();
|
||||
rmp::encode::write_bin(&mut wr, &body).unwrap();
|
||||
rmp::encode::write_uint(&mut wr, 1)?;
|
||||
rmp::encode::write_uint(&mut wr, 1)?;
|
||||
rmp::encode::write_sint(&mut wr, 1)?;
|
||||
rmp::encode::write_bin(&mut wr, &header)?;
|
||||
rmp::encode::write_bin(&mut wr, &body)?;
|
||||
|
||||
let data_len = (wr.len() - offset) as u32;
|
||||
wr[offset - 4..offset].copy_from_slice(&data_len.to_be_bytes());
|
||||
@@ -350,7 +351,8 @@ pub fn create_complex_xlmeta() -> Result<Vec<u8>> {
|
||||
}
|
||||
|
||||
// Sort by modification time (newest first)
|
||||
fm.versions.sort_by(|a, b| b.header.mod_time.cmp(&a.header.mod_time));
|
||||
fm.versions
|
||||
.sort_by_key(|v| (v.header.mod_time.is_none(), std::cmp::Reverse(v.header.mod_time)));
|
||||
|
||||
fm.marshal_msg()
|
||||
}
|
||||
|
||||
@@ -124,11 +124,7 @@ impl LockStats {
|
||||
pub fn avg_hold_time(&self) -> Duration {
|
||||
let total = self.total_hold_time_ns.load(Ordering::Relaxed);
|
||||
let count = self.locks_acquired.load(Ordering::Relaxed);
|
||||
if count == 0 {
|
||||
Duration::ZERO
|
||||
} else {
|
||||
Duration::from_nanos(total / count)
|
||||
}
|
||||
total.checked_div(count).map(Duration::from_nanos).unwrap_or(Duration::ZERO)
|
||||
}
|
||||
|
||||
/// Get maximum hold time.
|
||||
|
||||
@@ -342,11 +342,7 @@ impl TimeoutStats {
|
||||
pub fn avg_wait_time(&self) -> Duration {
|
||||
let total = self.total_wait_time_ns.load(Ordering::Relaxed);
|
||||
let count = self.total_operations.load(Ordering::Relaxed);
|
||||
if count == 0 {
|
||||
Duration::ZERO
|
||||
} else {
|
||||
Duration::from_nanos(total / count)
|
||||
}
|
||||
total.checked_div(count).map(Duration::from_nanos).unwrap_or(Duration::ZERO)
|
||||
}
|
||||
|
||||
/// Reset statistics.
|
||||
|
||||
@@ -255,7 +255,7 @@ impl AccessTracker {
|
||||
/// Get keys sorted by access count (descending).
|
||||
pub fn top_keys(&self, n: usize) -> Vec<(&String, &AccessRecord)> {
|
||||
let mut entries: Vec<_> = self.records.iter().collect();
|
||||
entries.sort_by(|a, b| b.1.count.cmp(&a.1.count));
|
||||
entries.sort_by_key(|entry| std::cmp::Reverse(entry.1.count));
|
||||
entries.into_iter().take(n).collect()
|
||||
}
|
||||
|
||||
|
||||
@@ -170,11 +170,10 @@ impl MetricsSnapshot {
|
||||
}
|
||||
|
||||
pub fn avg_wait_time(&self) -> Duration {
|
||||
if self.slow_path_success == 0 {
|
||||
Duration::ZERO
|
||||
} else {
|
||||
Duration::from_nanos(self.total_wait_time_ns / self.slow_path_success)
|
||||
}
|
||||
self.total_wait_time_ns
|
||||
.checked_div(self.slow_path_success)
|
||||
.map(Duration::from_nanos)
|
||||
.unwrap_or(Duration::ZERO)
|
||||
}
|
||||
|
||||
pub fn max_wait_time(&self) -> Duration {
|
||||
|
||||
@@ -603,11 +603,7 @@ async fn get_dir_size_async(path: &Path) -> Result<CapacityScanResult, std::io::
|
||||
} else if file_count > max_files_threshold {
|
||||
let overflow_count = file_count - max_files_threshold;
|
||||
let exact_prefix_count = file_count.min(max_files_threshold) as u64;
|
||||
let avg_prefix_size = if exact_prefix_count > 0 {
|
||||
exact_prefix_bytes / exact_prefix_count
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let avg_prefix_size = exact_prefix_bytes.checked_div(exact_prefix_count).unwrap_or(0);
|
||||
let estimated_overflow = avg_prefix_size.saturating_mul(overflow_count as u64);
|
||||
let estimated_size = exact_prefix_bytes.saturating_add(estimated_overflow);
|
||||
info!(
|
||||
|
||||
@@ -765,7 +765,7 @@ impl DataUsageCache {
|
||||
let mut leaves = Vec::new();
|
||||
let mut remove = total - limit;
|
||||
add(self, path, &mut leaves);
|
||||
leaves.sort_by(|a, b| a.objects.cmp(&b.objects));
|
||||
leaves.sort_by_key(|a| a.objects);
|
||||
|
||||
while remove > 0 && !leaves.is_empty() {
|
||||
let e = leaves.first().unwrap();
|
||||
|
||||
Reference in New Issue
Block a user