mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-12 16:16:55 +00:00
refactor(obs): migrate metrics runtime/schema and tighten migration guards (#2584)
This commit is contained in:
@@ -19,6 +19,9 @@ use crate::{
|
||||
types::{LockId, LockInfo, LockRequest, LockResponse, LockStatus, LockType},
|
||||
};
|
||||
use futures::future::join_all;
|
||||
use rustfs_io_metrics::{
|
||||
record_read_lock_held_acquire, record_read_lock_held_release, record_write_lock_held_acquire, record_write_lock_held_release,
|
||||
};
|
||||
use std::sync::{Arc, LazyLock};
|
||||
use std::time::Duration;
|
||||
use tokio::sync::mpsc;
|
||||
@@ -82,6 +85,7 @@ pub struct DistributedLockGuard {
|
||||
/// All underlying (LockId, client) entries that should be released when the
|
||||
/// guard is dropped.
|
||||
entries: Vec<(LockId, Arc<dyn LockClient>)>,
|
||||
lock_type: LockType,
|
||||
/// If true, Drop will not try to release (used if user manually released).
|
||||
disarmed: bool,
|
||||
}
|
||||
@@ -92,10 +96,12 @@ impl DistributedLockGuard {
|
||||
/// - `lock_id` is the id returned to the caller (`lock_id()`).
|
||||
/// - `entries` is the full list of underlying (LockId, client) pairs
|
||||
/// that should be released when this guard is dropped.
|
||||
pub(crate) fn new(lock_id: LockId, entries: Vec<(LockId, Arc<dyn LockClient>)>) -> Self {
|
||||
pub(crate) fn new(lock_id: LockId, entries: Vec<(LockId, Arc<dyn LockClient>)>, lock_type: LockType) -> Self {
|
||||
record_lock_held_acquire(lock_type);
|
||||
Self {
|
||||
lock_id,
|
||||
entries,
|
||||
lock_type,
|
||||
disarmed: false,
|
||||
}
|
||||
}
|
||||
@@ -108,6 +114,9 @@ impl DistributedLockGuard {
|
||||
/// Manually disarm the guard so dropping it won't release the lock.
|
||||
/// Call this if you explicitly released the lock elsewhere.
|
||||
pub fn disarm(&mut self) {
|
||||
if !self.disarmed {
|
||||
record_lock_held_release(self.lock_type);
|
||||
}
|
||||
self.disarmed = true;
|
||||
}
|
||||
|
||||
@@ -156,6 +165,7 @@ impl DistributedLockGuard {
|
||||
|
||||
// Disarm to prevent double-release on drop
|
||||
self.disarmed = true;
|
||||
record_lock_held_release(self.lock_type);
|
||||
success
|
||||
}
|
||||
}
|
||||
@@ -248,7 +258,7 @@ impl DistributedLock {
|
||||
.map(|info| info.id.clone())
|
||||
.unwrap_or_else(|| LockId::new_unique(&request.resource));
|
||||
|
||||
Ok(Some(DistributedLockGuard::new(aggregate_lock_id, individual_locks)))
|
||||
Ok(Some(DistributedLockGuard::new(aggregate_lock_id, individual_locks, request.lock_type)))
|
||||
} else {
|
||||
// Check if it's a timeout or quorum failure
|
||||
if let Some(error_msg) = &resp.error {
|
||||
@@ -523,3 +533,19 @@ impl DistributedLock {
|
||||
Ok((resp, individual_locks))
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn record_lock_held_acquire(lock_type: LockType) {
|
||||
match lock_type {
|
||||
LockType::Shared => record_read_lock_held_acquire(),
|
||||
LockType::Exclusive => record_write_lock_held_acquire(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn record_lock_held_release(lock_type: LockType) {
|
||||
match lock_type {
|
||||
LockType::Shared => record_read_lock_held_release(),
|
||||
LockType::Exclusive => record_write_lock_held_release(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@ use crate::fast_lock::{
|
||||
shard::LockShard,
|
||||
types::{LockMode, ObjectKey},
|
||||
};
|
||||
use rustfs_io_metrics::{
|
||||
record_read_lock_held_acquire, record_read_lock_held_release, record_write_lock_held_acquire, record_write_lock_held_release,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicU64, Ordering};
|
||||
|
||||
@@ -40,6 +43,7 @@ pub struct FastLockGuard {
|
||||
impl FastLockGuard {
|
||||
pub(crate) fn new(key: ObjectKey, mode: LockMode, owner: Arc<str>, shard: Arc<LockShard>) -> Self {
|
||||
let guard_id = GUARD_ID_COUNTER.fetch_add(1, Ordering::Relaxed);
|
||||
record_lock_held_acquire(mode);
|
||||
Self {
|
||||
key,
|
||||
mode,
|
||||
@@ -102,6 +106,7 @@ impl FastLockGuard {
|
||||
let success = shard.release_lock_with_guard(&self.key, &self.owner, self.mode, self.guard_id);
|
||||
if success {
|
||||
self.released = true;
|
||||
record_lock_held_release(self.mode);
|
||||
// Unregister the guard after successful release
|
||||
shard.unregister_guard(self.guard_id);
|
||||
}
|
||||
@@ -158,6 +163,9 @@ impl Drop for FastLockGuard {
|
||||
self.guard_id
|
||||
);
|
||||
}
|
||||
if success {
|
||||
record_lock_held_release(self.mode);
|
||||
}
|
||||
// Always unregister the guard to prevent leaks, regardless of release success
|
||||
shard.unregister_guard(self.guard_id);
|
||||
} else {
|
||||
@@ -168,6 +176,22 @@ impl Drop for FastLockGuard {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn record_lock_held_acquire(mode: LockMode) {
|
||||
match mode {
|
||||
LockMode::Shared => record_read_lock_held_acquire(),
|
||||
LockMode::Exclusive => record_write_lock_held_acquire(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn record_lock_held_release(mode: LockMode) {
|
||||
match mode {
|
||||
LockMode::Shared => record_read_lock_held_release(),
|
||||
LockMode::Exclusive => record_write_lock_held_release(),
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for FastLockGuard {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("FastLockGuard")
|
||||
|
||||
Reference in New Issue
Block a user