pub struct RwLock<T> { /* private fields */ }Expand description
A tracked read-write lock that automatically records contention metrics and integrates with deadlock detection.
This is a drop-in replacement for tokio::sync::RwLock with additional
observability features. It tracks read and write operations separately.
§Example
use async_inspect::sync::RwLock;
#[tokio::main]
async fn main() {
let lock = RwLock::new(vec![1, 2, 3], "shared_data");
// Multiple readers can access simultaneously
let lock = std::sync::Arc::new(lock);
let mut handles = vec![];
for i in 0..5 {
let l = lock.clone();
handles.push(tokio::spawn(async move {
let guard = l.read().await;
println!("Reader {}: {:?}", i, *guard);
}));
}
// Writer has exclusive access
{
let mut guard = lock.write().await;
guard.push(4);
}
for h in handles {
h.await.unwrap();
}
// Check contention metrics
let (read_metrics, write_metrics) = lock.metrics();
println!("Read acquisitions: {}", read_metrics.acquisitions);
println!("Write acquisitions: {}", write_metrics.acquisitions);
}Implementations§
Source§impl<T> RwLock<T>
impl<T> RwLock<T>
Sourcepub fn new(value: T, name: impl Into<String>) -> Self
pub fn new(value: T, name: impl Into<String>) -> Self
Create a new tracked RwLock with a name for identification.
§Arguments
value- The initial value to protectname- A descriptive name for debugging and metrics
§Example
use async_inspect::sync::RwLock;
use std::collections::HashMap;
let lock = RwLock::new(HashMap::<String, i32>::new(), "user_cache");Sourcepub async fn read(&self) -> RwLockReadGuard<'_, T>
pub async fn read(&self) -> RwLockReadGuard<'_, T>
Acquire a read lock, blocking until it’s available.
Multiple readers can hold the lock simultaneously, but writers must wait for all readers to release.
§Example
use async_inspect::sync::RwLock;
let lock = RwLock::new(42, "my_value");
let guard = lock.read().await;
println!("Value: {}", *guard);Sourcepub async fn write(&self) -> RwLockWriteGuard<'_, T>
pub async fn write(&self) -> RwLockWriteGuard<'_, T>
Acquire a write lock, blocking until it’s available.
Writers have exclusive access - no other readers or writers can hold the lock simultaneously.
§Example
use async_inspect::sync::RwLock;
let lock = RwLock::new(42, "my_value");
let mut guard = lock.write().await;
*guard = 100;Sourcepub fn try_read(&self) -> Option<RwLockReadGuard<'_, T>>
pub fn try_read(&self) -> Option<RwLockReadGuard<'_, T>>
Try to acquire a read lock immediately.
Returns None if a writer is holding the lock.
Sourcepub fn try_write(&self) -> Option<RwLockWriteGuard<'_, T>>
pub fn try_write(&self) -> Option<RwLockWriteGuard<'_, T>>
Try to acquire a write lock immediately.
Returns None if any readers or writers are holding the lock.
Sourcepub fn metrics(&self) -> (LockMetrics, LockMetrics)
pub fn metrics(&self) -> (LockMetrics, LockMetrics)
Get the current contention metrics for this RwLock.
Returns a tuple of (read_metrics, write_metrics).
§Example
use async_inspect::sync::RwLock;
let lock = RwLock::new(42, "my_value");
// ... some operations ...
let (read_metrics, write_metrics) = lock.metrics();
println!("Read acquisitions: {}", read_metrics.acquisitions);
println!("Write acquisitions: {}", write_metrics.acquisitions);Sourcepub fn read_metrics(&self) -> LockMetrics
pub fn read_metrics(&self) -> LockMetrics
Get only the read metrics.
Sourcepub fn write_metrics(&self) -> LockMetrics
pub fn write_metrics(&self) -> LockMetrics
Get only the write metrics.
Sourcepub fn reset_metrics(&self)
pub fn reset_metrics(&self)
Reset all contention metrics.
Sourcepub fn resource_id(&self) -> ResourceId
pub fn resource_id(&self) -> ResourceId
Get the resource ID for deadlock detection.
Sourcepub fn into_inner(self) -> T
pub fn into_inner(self) -> T
Consume the RwLock and return the inner value.
Trait Implementations§
Auto Trait Implementations§
impl<T> !Freeze for RwLock<T>
impl<T> !RefUnwindSafe for RwLock<T>
impl<T> Send for RwLock<T>where
T: Send,
impl<T> Sync for RwLock<T>
impl<T> Unpin for RwLock<T>where
T: Unpin,
impl<T> !UnwindSafe for RwLock<T>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> FutureExt for T
impl<T> FutureExt for T
Source§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
Source§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more