mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-25 13:36:50 +00:00
fix(ci): repair post-merge build gates
This commit is contained in:
@@ -56,6 +56,7 @@ use crate::storage_api_contracts::{
|
|||||||
bucket::{BucketOperations, BucketOptions, MakeBucketOptions},
|
bucket::{BucketOperations, BucketOptions, MakeBucketOptions},
|
||||||
heal::HealOperations as _,
|
heal::HealOperations as _,
|
||||||
list::ListOperations as _,
|
list::ListOperations as _,
|
||||||
|
namespace::NamespaceLocking as _,
|
||||||
object::{EcstoreObjectIO, HTTPPreconditions, ObjectIO as _, ObjectOperations as _},
|
object::{EcstoreObjectIO, HTTPPreconditions, ObjectIO as _, ObjectOperations as _},
|
||||||
};
|
};
|
||||||
use crate::{core::sets::Sets, store::ECStore};
|
use crate::{core::sets::Sets, store::ECStore};
|
||||||
@@ -9035,10 +9036,8 @@ impl ECStore {
|
|||||||
) -> Result<Vec<DecommissionUnresolvedEntry>> {
|
) -> Result<Vec<DecommissionUnresolvedEntry>> {
|
||||||
self.ensure_decommission_generation_current(idx, generation).await?;
|
self.ensure_decommission_generation_current(idx, generation).await?;
|
||||||
let operation_gate = self.ctx.data_movement_operation_gate();
|
let operation_gate = self.ctx.data_movement_operation_gate();
|
||||||
self.run_guarded_decommission_side_effect(rx, &operation_gate, || {
|
self.run_guarded_decommission_side_effect(rx, &operation_gate, || self.check_after_decommission_unfenced(idx, generation))
|
||||||
self.check_after_decommission_unfenced(idx, generation)
|
.await
|
||||||
})
|
|
||||||
.await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn check_after_decommission_unfenced(
|
async fn check_after_decommission_unfenced(
|
||||||
@@ -11115,10 +11114,9 @@ mod pools_tests {
|
|||||||
load_decommission_entry_versions, local_decommission_queue_prefix, mark_decommission_bucket_done,
|
load_decommission_entry_versions, local_decommission_queue_prefix, mark_decommission_bucket_done,
|
||||||
merge_decommission_durable_ilm_receipts, merge_pool_meta_updates_for_save, merge_pool_status_refresh,
|
merge_decommission_durable_ilm_receipts, merge_pool_meta_updates_for_save, merge_pool_status_refresh,
|
||||||
missing_decommission_worker_prefix, observe_decommission_terminal_reload_result, pool_meta_has_active_decommission,
|
missing_decommission_worker_prefix, observe_decommission_terminal_reload_result, pool_meta_has_active_decommission,
|
||||||
publish_pool_meta_updates, reconcile_decommission_meta_buckets,
|
publish_pool_meta_updates, reconcile_decommission_meta_buckets, reconcile_decommission_unresolved_entries_for_completion,
|
||||||
reconcile_decommission_unresolved_entries_for_completion, record_decommission_unresolved_entry,
|
record_decommission_unresolved_entry, require_decommission_store, reserve_decommission_start_cancelers,
|
||||||
require_decommission_store,
|
resolve_decommission_bucket_state, resolve_decommission_check_after_list_result,
|
||||||
reserve_decommission_start_cancelers, resolve_decommission_bucket_state, resolve_decommission_check_after_list_result,
|
|
||||||
resolve_decommission_entry_cleanup_delete_result, resolve_decommission_entry_exact_versions,
|
resolve_decommission_entry_cleanup_delete_result, resolve_decommission_entry_exact_versions,
|
||||||
resolve_decommission_entry_reload_result, resolve_decommission_listing_worker_result,
|
resolve_decommission_entry_reload_result, resolve_decommission_listing_worker_result,
|
||||||
resolve_decommission_optional_bucket_config_result, resolve_decommission_pool_meta_reload_result,
|
resolve_decommission_optional_bucket_config_result, resolve_decommission_pool_meta_reload_result,
|
||||||
|
|||||||
@@ -35,7 +35,10 @@ use crate::disk::{
|
|||||||
error::{DiskError, Error, FileAccessDeniedWithContext, Result},
|
error::{DiskError, Error, FileAccessDeniedWithContext, Result},
|
||||||
error_conv::{to_access_error, to_file_error, to_unformatted_disk_error, to_volume_error},
|
error_conv::{to_access_error, to_file_error, to_unformatted_disk_error, to_volume_error},
|
||||||
format::FormatV3,
|
format::FormatV3,
|
||||||
fs::{O_APPEND, O_CREATE, O_RDONLY, O_TRUNC, O_WRONLY, access, cached_access, invalidate_bucket_cache, lstat, lstat_std, remove, remove_all_std, remove_std, rename},
|
fs::{
|
||||||
|
O_APPEND, O_CREATE, O_RDONLY, O_TRUNC, O_WRONLY, access, cached_access, invalidate_bucket_cache, lstat, lstat_std,
|
||||||
|
remove, remove_all_std, remove_std, rename,
|
||||||
|
},
|
||||||
is_quota_mutation_fence_path, os,
|
is_quota_mutation_fence_path, os,
|
||||||
os::{check_path_length, is_dir_not_empty_error, is_empty_dir, is_root_disk, rename_all, rename_all_ignore_missing_source},
|
os::{check_path_length, is_dir_not_empty_error, is_empty_dir, is_root_disk, rename_all, rename_all_ignore_missing_source},
|
||||||
quota_mutation_fence_path,
|
quota_mutation_fence_path,
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ pub async fn test_store_with_persisted_rebalance_meta(
|
|||||||
rebalance_meta: tokio::sync::RwLock::new(Some(meta)),
|
rebalance_meta: tokio::sync::RwLock::new(Some(meta)),
|
||||||
decommission_cancelers: tokio::sync::RwLock::new(vec![None]),
|
decommission_cancelers: tokio::sync::RwLock::new(vec![None]),
|
||||||
start_gate: tokio::sync::Mutex::new(()),
|
start_gate: tokio::sync::Mutex::new(()),
|
||||||
pool_meta_save_gate: tokio::sync::Mutex::new(()),
|
pool_meta_save_gate: tokio::sync::Mutex::default(),
|
||||||
ctx,
|
ctx,
|
||||||
bucket_fence_registry: std::sync::Arc::default(),
|
bucket_fence_registry: std::sync::Arc::default(),
|
||||||
});
|
});
|
||||||
@@ -168,7 +168,7 @@ async fn test_two_pool_stores_with_contexts(
|
|||||||
rebalance_meta: tokio::sync::RwLock::new(rebalance_meta.clone()),
|
rebalance_meta: tokio::sync::RwLock::new(rebalance_meta.clone()),
|
||||||
decommission_cancelers: tokio::sync::RwLock::new(vec![None, None]),
|
decommission_cancelers: tokio::sync::RwLock::new(vec![None, None]),
|
||||||
start_gate: tokio::sync::Mutex::new(()),
|
start_gate: tokio::sync::Mutex::new(()),
|
||||||
pool_meta_save_gate: tokio::sync::Mutex::new(()),
|
pool_meta_save_gate: tokio::sync::Mutex::default(),
|
||||||
ctx: store_ctx,
|
ctx: store_ctx,
|
||||||
bucket_fence_registry: std::sync::Arc::default(),
|
bucket_fence_registry: std::sync::Arc::default(),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -33,7 +33,13 @@ use crate::scanner_io::{
|
|||||||
SCANNER_SKIP_FILE_ERROR, ScannerIODisk as _, is_scanner_metadata_corrupt_error, is_scanner_metadata_transient_error,
|
SCANNER_SKIP_FILE_ERROR, ScannerIODisk as _, is_scanner_metadata_corrupt_error, is_scanner_metadata_transient_error,
|
||||||
};
|
};
|
||||||
use crate::sleeper::DynamicSleeper;
|
use crate::sleeper::DynamicSleeper;
|
||||||
use crate::storage_api::owner::{EcstoreEventArgs, ecstore_send_event};
|
use crate::storage_api::owner::{
|
||||||
|
EcstoreBucketLifecycleConfiguration as BucketLifecycleConfiguration, EcstoreEventArgs,
|
||||||
|
EcstoreLifecycleRuleFilter as LifecycleRuleFilter, EcstoreObjectLockConfiguration as ObjectLockConfiguration,
|
||||||
|
EcstoreVersioningConfiguration as VersioningConfiguration, ecstore_send_event,
|
||||||
|
};
|
||||||
|
#[cfg(test)]
|
||||||
|
use crate::storage_api::owner::{EcstoreExpirationStatus as ExpirationStatus, EcstoreLifecycleRule as LifecycleRule};
|
||||||
use metrics::{counter, describe_counter};
|
use metrics::{counter, describe_counter};
|
||||||
use rustfs_common::heal_channel::{
|
use rustfs_common::heal_channel::{
|
||||||
HEAL_DELETE_DANGLING, HealAdmissionDropReason, HealAdmissionResult, HealChannelPriority, HealChannelRequest,
|
HEAL_DELETE_DANGLING, HealAdmissionDropReason, HealAdmissionResult, HealChannelPriority, HealChannelRequest,
|
||||||
@@ -49,9 +55,6 @@ use rustfs_filemeta::{
|
|||||||
MetaCacheHealCandidateKind,
|
MetaCacheHealCandidateKind,
|
||||||
};
|
};
|
||||||
use rustfs_utils::path::{SLASH_SEPARATOR, path_join_buf};
|
use rustfs_utils::path::{SLASH_SEPARATOR, path_join_buf};
|
||||||
use s3s::dto::{BucketLifecycleConfiguration, LifecycleRuleFilter, ObjectLockConfiguration, VersioningConfiguration};
|
|
||||||
#[cfg(test)]
|
|
||||||
use s3s::dto::{ExpirationStatus, LifecycleRule};
|
|
||||||
use time::OffsetDateTime;
|
use time::OffsetDateTime;
|
||||||
use tokio::select;
|
use tokio::select;
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
|
|||||||
@@ -17,6 +17,13 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
pub(crate) use s3s::dto::{
|
||||||
|
BucketLifecycleConfiguration as EcstoreBucketLifecycleConfiguration, LifecycleRuleFilter as EcstoreLifecycleRuleFilter,
|
||||||
|
ObjectLockConfiguration as EcstoreObjectLockConfiguration, VersioningConfiguration as EcstoreVersioningConfiguration,
|
||||||
|
};
|
||||||
|
#[cfg(test)]
|
||||||
|
pub(crate) use s3s::dto::{ExpirationStatus as EcstoreExpirationStatus, LifecycleRule as EcstoreLifecycleRule};
|
||||||
|
|
||||||
pub(crate) use rustfs_ecstore::api::bucket::bucket_target_sys::BucketTargetSys as EcstoreBucketTargetSys;
|
pub(crate) use rustfs_ecstore::api::bucket::bucket_target_sys::BucketTargetSys as EcstoreBucketTargetSys;
|
||||||
pub(crate) use rustfs_ecstore::api::bucket::lifecycle::bucket_lifecycle_audit::LcEventSrc as EcstoreLcEventSrc;
|
pub(crate) use rustfs_ecstore::api::bucket::lifecycle::bucket_lifecycle_audit::LcEventSrc as EcstoreLcEventSrc;
|
||||||
pub(crate) use rustfs_ecstore::api::bucket::lifecycle::bucket_lifecycle_ops::{
|
pub(crate) use rustfs_ecstore::api::bucket::lifecycle::bucket_lifecycle_ops::{
|
||||||
@@ -111,12 +118,13 @@ pub(crate) mod owner {
|
|||||||
|
|
||||||
pub(crate) use super::{
|
pub(crate) use super::{
|
||||||
ECSTORE_BUCKET_META_PREFIX, ECSTORE_RUSTFS_META_BUCKET, ECSTORE_STORAGE_FORMAT_FILE, ECSTORE_STORAGECLASS_RRS,
|
ECSTORE_BUCKET_META_PREFIX, ECSTORE_RUSTFS_META_BUCKET, ECSTORE_STORAGE_FORMAT_FILE, ECSTORE_STORAGECLASS_RRS,
|
||||||
ECSTORE_STORAGECLASS_STANDARD, ECSTORE_TRANSITION_COMPLETE, EcstoreBucketTargetSys, EcstoreBucketVersioningSys,
|
ECSTORE_STORAGECLASS_STANDARD, ECSTORE_TRANSITION_COMPLETE, EcstoreBucketLifecycleConfiguration, EcstoreBucketTargetSys,
|
||||||
EcstoreDisk, EcstoreDiskAPI, EcstoreDiskBytes, EcstoreDiskError, EcstoreDiskInfo, EcstoreDiskInfoOptions,
|
EcstoreBucketVersioningSys, EcstoreDisk, EcstoreDiskAPI, EcstoreDiskBytes, EcstoreDiskError, EcstoreDiskInfo,
|
||||||
EcstoreDiskLocation, EcstoreDiskResult, EcstoreErrorType, EcstoreEvaluator, EcstoreEvent, EcstoreEventArgs,
|
EcstoreDiskInfoOptions, EcstoreDiskLocation, EcstoreDiskResult, EcstoreErrorType, EcstoreEvaluator, EcstoreEvent,
|
||||||
EcstoreLcEventSrc, EcstoreLifecycle, EcstoreListPathRawOptions, EcstoreNsScannerOpenRequest, EcstoreObjectOpts,
|
EcstoreEventArgs, EcstoreLcEventSrc, EcstoreLifecycle, EcstoreLifecycleRuleFilter, EcstoreListPathRawOptions,
|
||||||
EcstoreReplicationConfigurationExt, EcstoreReplicationScannerBridge, EcstoreResultType, EcstoreScanGuard,
|
EcstoreNsScannerOpenRequest, EcstoreObjectLockConfiguration, EcstoreObjectOpts, EcstoreReplicationConfigurationExt,
|
||||||
EcstoreSetDisks, EcstoreStorageError, EcstoreStore, EcstoreVersioningApi, SCANNER_PUBLICATION_LEASE_FENCE_METADATA_KEY,
|
EcstoreReplicationScannerBridge, EcstoreResultType, EcstoreScanGuard, EcstoreSetDisks, EcstoreStorageError, EcstoreStore,
|
||||||
|
EcstoreVersioningApi, EcstoreVersioningConfiguration, SCANNER_PUBLICATION_LEASE_FENCE_METADATA_KEY,
|
||||||
SCANNER_PUBLICATION_LEASE_TTL_MS, ScannerReplicationHealObject, ScannerReplicationHealResult,
|
SCANNER_PUBLICATION_LEASE_TTL_MS, ScannerReplicationHealObject, ScannerReplicationHealResult,
|
||||||
ScannerReplicationQueueAdmission, ecstore_apply_expiry_rule, ecstore_apply_transition_rule, ecstore_expiry_state_handle,
|
ScannerReplicationQueueAdmission, ecstore_apply_expiry_rule, ecstore_apply_transition_rule, ecstore_expiry_state_handle,
|
||||||
ecstore_get_global_tier_config_mgr, ecstore_get_lifecycle_config, ecstore_get_object_lock_config,
|
ecstore_get_global_tier_config_mgr, ecstore_get_lifecycle_config, ecstore_get_object_lock_config,
|
||||||
@@ -131,9 +139,9 @@ pub(crate) mod owner {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) use super::{
|
pub(crate) use super::{
|
||||||
EcstoreDiskOption, EcstoreDiskStore, EcstoreEndpoint, EcstoreEndpointServerPools, EcstoreEndpoints,
|
EcstoreDiskOption, EcstoreDiskStore, EcstoreEndpoint, EcstoreEndpointServerPools, EcstoreEndpoints,
|
||||||
EcstoreInstanceContext, EcstorePoolDecommissionInfo, EcstorePoolEndpoints, EcstoreRebalStatus, EcstoreRebalanceInfo,
|
EcstoreExpirationStatus, EcstoreInstanceContext, EcstoreLifecycleRule, EcstorePoolDecommissionInfo, EcstorePoolEndpoints,
|
||||||
EcstoreRebalanceMeta, EcstoreRebalanceStats, ecstore_config_init, ecstore_init_bucket_metadata_sys,
|
EcstoreRebalStatus, EcstoreRebalanceInfo, EcstoreRebalanceMeta, EcstoreRebalanceStats, ecstore_config_init,
|
||||||
ecstore_init_local_disks_with_instance_ctx, ecstore_new_disk,
|
ecstore_init_bucket_metadata_sys, ecstore_init_local_disks_with_instance_ctx, ecstore_new_disk,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-2
@@ -57,7 +57,7 @@ pyroscope = ["rustfs-obs/pyroscope"]
|
|||||||
# Tokio runtime telemetry. Requires `--cfg tokio_unstable`; use `make build-profiling`.
|
# Tokio runtime telemetry. Requires `--cfg tokio_unstable`; use `make build-profiling`.
|
||||||
dial9 = ["rustfs-obs/dial9"]
|
dial9 = ["rustfs-obs/dial9"]
|
||||||
# Allocator features
|
# Allocator features
|
||||||
mimalloc = ["dep:rustfs-mimalloc", "dep:rustfs-mimalloc-sys"]
|
mimalloc = ["dep:rustfs-mimalloc"]
|
||||||
jemalloc = ["dep:tikv-jemallocator"]
|
jemalloc = ["dep:tikv-jemallocator"]
|
||||||
hotpath = [
|
hotpath = [
|
||||||
"hotpath/hotpath",
|
"hotpath/hotpath",
|
||||||
@@ -345,7 +345,6 @@ rustfs-mimalloc = { workspace = true, optional = true }
|
|||||||
libsystemd.workspace = true
|
libsystemd.workspace = true
|
||||||
|
|
||||||
[target.'cfg(not(target_os = "windows"))'.dependencies]
|
[target.'cfg(not(target_os = "windows"))'.dependencies]
|
||||||
rustfs-mimalloc-sys = { workspace = true, optional = true }
|
|
||||||
tikv-jemallocator = { version = "0.6", optional = true }
|
tikv-jemallocator = { version = "0.6", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|||||||
@@ -169,15 +169,25 @@ impl AllocatorReclaimController {
|
|||||||
|
|
||||||
/// Return the allocator backend name used by reclaim and memory metrics.
|
/// Return the allocator backend name used by reclaim and memory metrics.
|
||||||
pub fn allocator_backend() -> &'static str {
|
pub fn allocator_backend() -> &'static str {
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(all(feature = "mimalloc", not(target_os = "windows")))]
|
||||||
{
|
{
|
||||||
"mimalloc"
|
"mimalloc"
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(all(feature = "mimalloc", target_os = "windows"))]
|
||||||
{
|
{
|
||||||
"mimalloc-windows"
|
"mimalloc-windows"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(all(not(feature = "mimalloc"), feature = "jemalloc"))]
|
||||||
|
{
|
||||||
|
"jemalloc"
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(any(feature = "mimalloc", feature = "jemalloc")))]
|
||||||
|
{
|
||||||
|
"system"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn active_requests() -> u64 {
|
fn active_requests() -> u64 {
|
||||||
@@ -368,15 +378,15 @@ pub fn allocator_reclaim_controller_snapshot(ctx: &CancellationToken) -> Allocat
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(all(feature = "mimalloc", not(target_os = "windows")))]
|
||||||
fn collect_allocator_memory(force: bool) -> Result<(), String> {
|
fn collect_allocator_memory(force: bool) -> Result<(), String> {
|
||||||
rustfs_mimalloc::MiMalloc::collect(force);
|
rustfs_mimalloc::MiMalloc::collect(force);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(not(all(feature = "mimalloc", not(target_os = "windows"))))]
|
||||||
fn collect_allocator_memory(_force: bool) -> Result<(), String> {
|
fn collect_allocator_memory(_force: bool) -> Result<(), String> {
|
||||||
Err("allocator reclaim is not supported on Windows".to_string())
|
Err("allocator reclaim requires mimalloc on a non-Windows target".to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Execute one allocator collection and publish the outcome metrics.
|
/// Execute one allocator collection and publish the outcome metrics.
|
||||||
|
|||||||
@@ -65,8 +65,6 @@ use super::storage_api::object_usecase::contract::http::HTTPPreconditions;
|
|||||||
use super::storage_api::object_usecase::contract::namespace::NamespaceLocking;
|
use super::storage_api::object_usecase::contract::namespace::NamespaceLocking;
|
||||||
use super::storage_api::object_usecase::contract::object::{ObjectIO as _, ObjectOperations as _};
|
use super::storage_api::object_usecase::contract::object::{ObjectIO as _, ObjectOperations as _};
|
||||||
use super::storage_api::object_usecase::contract::range::HTTPRangeSpec;
|
use super::storage_api::object_usecase::contract::range::HTTPRangeSpec;
|
||||||
#[cfg(test)]
|
|
||||||
use super::storage_api::object_usecase::data_usage::apply_bucket_usage_memory_overlay;
|
|
||||||
use super::storage_api::object_usecase::data_usage::{
|
use super::storage_api::object_usecase::data_usage::{
|
||||||
quota_object_size, record_bucket_delete_marker_memory, record_bucket_object_delete_memory,
|
quota_object_size, record_bucket_delete_marker_memory, record_bucket_object_delete_memory,
|
||||||
record_bucket_object_version_write_memory, record_bucket_object_write_memory,
|
record_bucket_object_version_write_memory, record_bucket_object_write_memory,
|
||||||
@@ -18082,7 +18080,7 @@ mod tests {
|
|||||||
|
|
||||||
async fn observed_bucket_usage(bucket: &str) -> Option<u64> {
|
async fn observed_bucket_usage(bucket: &str) -> Option<u64> {
|
||||||
let mut usage = rustfs_data_usage::DataUsageInfo::default();
|
let mut usage = rustfs_data_usage::DataUsageInfo::default();
|
||||||
crate::app::storage_api::object_usecase::data_usage::apply_bucket_usage_memory_overlay(&mut usage).await;
|
apply_bucket_usage_memory_overlay(&mut usage).await;
|
||||||
usage.buckets_usage.get(bucket).map(|value| value.size)
|
usage.buckets_usage.get(bucket).map(|value| value.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,11 @@
|
|||||||
//! tests where you start one server in a background task, run all your
|
//! tests where you start one server in a background task, run all your
|
||||||
//! tests, and then shut it down.
|
//! tests, and then shut it down.
|
||||||
|
|
||||||
|
#[cfg(all(feature = "mimalloc", feature = "jemalloc"))]
|
||||||
|
compile_error!("allocator features 'mimalloc' and 'jemalloc' are mutually exclusive");
|
||||||
|
#[cfg(all(feature = "jemalloc", target_os = "windows"))]
|
||||||
|
compile_error!("allocator feature 'jemalloc' is not supported on Windows");
|
||||||
|
|
||||||
/// Scope-based hotpath measurement for `#[async_trait]` methods, where
|
/// Scope-based hotpath measurement for `#[async_trait]` methods, where
|
||||||
/// `#[hotpath::measure]` would only time the boxed-future construction.
|
/// `#[hotpath::measure]` would only time the boxed-future construction.
|
||||||
/// The guard records wall time from this statement until the enclosing
|
/// The guard records wall time from this statement until the enclosing
|
||||||
|
|||||||
+65
-6
@@ -12,14 +12,29 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#[cfg(all(feature = "hotpath", feature = "hotpath-alloc"))]
|
#[cfg(all(
|
||||||
|
feature = "hotpath",
|
||||||
|
feature = "hotpath-alloc",
|
||||||
|
feature = "mimalloc",
|
||||||
|
not(feature = "jemalloc")
|
||||||
|
))]
|
||||||
use std::alloc::{GlobalAlloc, Layout};
|
use std::alloc::{GlobalAlloc, Layout};
|
||||||
|
|
||||||
#[cfg(all(feature = "hotpath", feature = "hotpath-alloc"))]
|
#[cfg(all(
|
||||||
|
feature = "hotpath",
|
||||||
|
feature = "hotpath-alloc",
|
||||||
|
feature = "mimalloc",
|
||||||
|
not(feature = "jemalloc")
|
||||||
|
))]
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct MiMallocAllocator;
|
struct MiMallocAllocator;
|
||||||
|
|
||||||
#[cfg(all(feature = "hotpath", feature = "hotpath-alloc"))]
|
#[cfg(all(
|
||||||
|
feature = "hotpath",
|
||||||
|
feature = "hotpath-alloc",
|
||||||
|
feature = "mimalloc",
|
||||||
|
not(feature = "jemalloc")
|
||||||
|
))]
|
||||||
// SAFETY: allocation operations are forwarded unchanged to MiMalloc, so
|
// SAFETY: allocation operations are forwarded unchanged to MiMalloc, so
|
||||||
// MiMalloc's GlobalAlloc guarantees apply to every returned pointer and layout.
|
// MiMalloc's GlobalAlloc guarantees apply to every returned pointer and layout.
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
@@ -45,21 +60,65 @@ unsafe impl GlobalAlloc for MiMallocAllocator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(feature = "hotpath", feature = "hotpath-alloc"))]
|
#[cfg(all(
|
||||||
|
feature = "hotpath",
|
||||||
|
feature = "hotpath-alloc",
|
||||||
|
feature = "mimalloc",
|
||||||
|
not(feature = "jemalloc")
|
||||||
|
))]
|
||||||
#[global_allocator]
|
#[global_allocator]
|
||||||
static GLOBAL: hotpath::CountingAllocator<MiMallocAllocator> = hotpath::CountingAllocator::with(MiMallocAllocator);
|
static GLOBAL: hotpath::CountingAllocator<MiMallocAllocator> = hotpath::CountingAllocator::with(MiMallocAllocator);
|
||||||
|
|
||||||
#[cfg(not(all(feature = "hotpath", feature = "hotpath-alloc")))]
|
#[cfg(all(
|
||||||
|
feature = "hotpath",
|
||||||
|
feature = "hotpath-alloc",
|
||||||
|
feature = "jemalloc",
|
||||||
|
not(feature = "mimalloc"),
|
||||||
|
not(target_os = "windows")
|
||||||
|
))]
|
||||||
|
#[global_allocator]
|
||||||
|
static GLOBAL: hotpath::CountingAllocator<tikv_jemallocator::Jemalloc> =
|
||||||
|
hotpath::CountingAllocator::with(tikv_jemallocator::Jemalloc);
|
||||||
|
|
||||||
|
#[cfg(all(
|
||||||
|
feature = "hotpath",
|
||||||
|
feature = "hotpath-alloc",
|
||||||
|
not(any(feature = "mimalloc", feature = "jemalloc"))
|
||||||
|
))]
|
||||||
|
#[global_allocator]
|
||||||
|
static GLOBAL: hotpath::CountingAllocator<std::alloc::System> = hotpath::CountingAllocator::with(std::alloc::System);
|
||||||
|
|
||||||
|
#[cfg(all(
|
||||||
|
not(all(feature = "hotpath", feature = "hotpath-alloc")),
|
||||||
|
feature = "mimalloc",
|
||||||
|
not(feature = "jemalloc")
|
||||||
|
))]
|
||||||
#[global_allocator]
|
#[global_allocator]
|
||||||
static GLOBAL: rustfs_mimalloc::MiMalloc = rustfs_mimalloc::MiMalloc;
|
static GLOBAL: rustfs_mimalloc::MiMalloc = rustfs_mimalloc::MiMalloc;
|
||||||
|
|
||||||
|
#[cfg(all(
|
||||||
|
not(all(feature = "hotpath", feature = "hotpath-alloc")),
|
||||||
|
feature = "jemalloc",
|
||||||
|
not(feature = "mimalloc"),
|
||||||
|
not(target_os = "windows")
|
||||||
|
))]
|
||||||
|
#[global_allocator]
|
||||||
|
static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let _hotpath_guard = hotpath::HotpathGuardBuilder::new("main").build();
|
let _hotpath_guard = hotpath::HotpathGuardBuilder::new("main").build();
|
||||||
|
|
||||||
rustfs::startup_entrypoint::run_process();
|
rustfs::startup_entrypoint::run_process();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(test, feature = "hotpath", feature = "hotpath-alloc", not(target_os = "windows")))]
|
#[cfg(all(
|
||||||
|
test,
|
||||||
|
feature = "hotpath",
|
||||||
|
feature = "hotpath-alloc",
|
||||||
|
feature = "mimalloc",
|
||||||
|
not(feature = "jemalloc"),
|
||||||
|
not(target_os = "windows")
|
||||||
|
))]
|
||||||
mod tests {
|
mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
// SAFETY: This test inspects a live allocation pointer with mimalloc's heap
|
// SAFETY: This test inspects a live allocation pointer with mimalloc's heap
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ use rustfs_io_metrics::{
|
|||||||
record_cpu_usage, record_memory_usage, record_process_memory_split,
|
record_cpu_usage, record_memory_usage, record_process_memory_split,
|
||||||
};
|
};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
#[cfg(any(feature = "mimalloc", test))]
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::{Arc, Mutex, OnceLock};
|
use std::sync::{Arc, Mutex, OnceLock};
|
||||||
@@ -228,6 +229,7 @@ fn read_cgroup_memory_snapshot() -> Option<CgroupMemorySnapshot> {
|
|||||||
read_cgroup_v2().or_else(read_cgroup_v1)
|
read_cgroup_v2().or_else(read_cgroup_v1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "mimalloc")]
|
||||||
fn read_allocator_memory_snapshot() -> Option<AllocatorMemorySnapshot> {
|
fn read_allocator_memory_snapshot() -> Option<AllocatorMemorySnapshot> {
|
||||||
let json = rustfs_mimalloc::MiMalloc::stats_json();
|
let json = rustfs_mimalloc::MiMalloc::stats_json();
|
||||||
if json.is_empty() {
|
if json.is_empty() {
|
||||||
@@ -240,6 +242,12 @@ fn read_allocator_memory_snapshot() -> Option<AllocatorMemorySnapshot> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "mimalloc"))]
|
||||||
|
fn read_allocator_memory_snapshot() -> Option<AllocatorMemorySnapshot> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(any(feature = "mimalloc", test))]
|
||||||
fn numeric_json_value(value: &Value) -> Option<u64> {
|
fn numeric_json_value(value: &Value) -> Option<u64> {
|
||||||
match value {
|
match value {
|
||||||
Value::Number(number) => number
|
Value::Number(number) => number
|
||||||
@@ -250,6 +258,7 @@ fn numeric_json_value(value: &Value) -> Option<u64> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(feature = "mimalloc", test))]
|
||||||
fn numeric_json_field(value: &Value, field: &str) -> Option<u64> {
|
fn numeric_json_field(value: &Value, field: &str) -> Option<u64> {
|
||||||
match value {
|
match value {
|
||||||
Value::Object(fields) => fields
|
Value::Object(fields) => fields
|
||||||
@@ -261,6 +270,7 @@ fn numeric_json_field(value: &Value, field: &str) -> Option<u64> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(feature = "mimalloc", test))]
|
||||||
fn mimalloc_stat_field(value: &Value, metric: &str, field: &str) -> Option<u64> {
|
fn mimalloc_stat_field(value: &Value, metric: &str, field: &str) -> Option<u64> {
|
||||||
match value {
|
match value {
|
||||||
Value::Object(fields) => {
|
Value::Object(fields) => {
|
||||||
@@ -277,10 +287,12 @@ fn mimalloc_stat_field(value: &Value, metric: &str, field: &str) -> Option<u64>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(feature = "mimalloc", test))]
|
||||||
fn mimalloc_stat_current(value: &Value, metric: &str) -> Option<u64> {
|
fn mimalloc_stat_current(value: &Value, metric: &str) -> Option<u64> {
|
||||||
mimalloc_stat_field(value, metric, "current")
|
mimalloc_stat_field(value, metric, "current")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(feature = "mimalloc", test))]
|
||||||
fn mimalloc_stat_sum(value: &Value, metrics: &[&str], field: &str) -> Option<u64> {
|
fn mimalloc_stat_sum(value: &Value, metrics: &[&str], field: &str) -> Option<u64> {
|
||||||
metrics
|
metrics
|
||||||
.iter()
|
.iter()
|
||||||
@@ -289,6 +301,7 @@ fn mimalloc_stat_sum(value: &Value, metrics: &[&str], field: &str) -> Option<u64
|
|||||||
.filter(|value| *value > 0)
|
.filter(|value| *value > 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(feature = "mimalloc", test))]
|
||||||
fn parse_mimalloc_stats_json(stats_json: &str) -> Option<AllocatorMemoryObservation> {
|
fn parse_mimalloc_stats_json(stats_json: &str) -> Option<AllocatorMemoryObservation> {
|
||||||
let value = serde_json::from_str::<Value>(stats_json).ok()?;
|
let value = serde_json::from_str::<Value>(stats_json).ok()?;
|
||||||
let malloc_metrics = ["malloc_normal", "malloc_huge"];
|
let malloc_metrics = ["malloc_normal", "malloc_huge"];
|
||||||
@@ -545,8 +558,10 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn read_allocator_memory_snapshot_uses_mimalloc_stats_json() {
|
fn read_allocator_memory_snapshot_uses_mimalloc_stats_json() {
|
||||||
let snapshot = super::read_allocator_memory_snapshot();
|
let snapshot = super::read_allocator_memory_snapshot();
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(all(feature = "mimalloc", not(target_os = "windows")))]
|
||||||
assert!(snapshot.is_some(), "allocator snapshot should be available on non-Windows");
|
assert!(snapshot.is_some(), "allocator snapshot should be available on non-Windows");
|
||||||
|
#[cfg(not(feature = "mimalloc"))]
|
||||||
|
assert!(snapshot.is_none(), "allocator snapshot should be absent without mimalloc");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
Reference in New Issue
Block a user