Centralize lifecycle state updates and fix systemd running status (#2567)

This commit is contained in:
houseme
2026-04-17 11:20:11 +08:00
committed by GitHub
parent 6b4172998b
commit 478720d2ee
28 changed files with 230 additions and 213 deletions
+1 -1
View File
@@ -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 {
+1 -5
View File
@@ -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),
-3
View File
@@ -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())),
);
}
_ => {}
}
+3 -3
View File
@@ -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);
+2 -1
View File
@@ -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;
+2 -1
View File
@@ -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;
+3 -3
View File
@@ -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.
+1 -1
View File
@@ -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;
};
+2 -4
View File
@@ -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" => {
+14
View File
@@ -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};
+6 -8
View File
@@ -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 {
+9 -7
View File
@@ -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()
}
+1 -5
View File
@@ -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.
+1 -5
View File
@@ -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.
+1 -1
View File
@@ -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()
}
+4 -5
View File
@@ -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 {
+1 -5
View File
@@ -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!(
+1 -1
View File
@@ -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();