-
Notifications
You must be signed in to change notification settings - Fork 476
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(pageserver): make partitioning an ArcSwap (#10377)
## Problem gc-compaction needs the partitioning data to decide the job split. This refactor allows concurrent access/computing the partitioning. ## Summary of changes Make `partitioning` an ArcSwap so that others can access the partitioning while we compute it. Fully eliminate the `repartition is called concurrently` warning when gc-compaction is going on. --------- Signed-off-by: Alex Chi Z <[email protected]>
- Loading branch information
Showing
4 changed files
with
70 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
//! A wrapper around `ArcSwap` that ensures there is only one writer at a time and writes | ||
//! don't block reads. | ||
use arc_swap::ArcSwap; | ||
use std::sync::Arc; | ||
use tokio::sync::TryLockError; | ||
|
||
pub struct GuardArcSwap<T> { | ||
inner: ArcSwap<T>, | ||
guard: tokio::sync::Mutex<()>, | ||
} | ||
|
||
pub struct Guard<'a, T> { | ||
_guard: tokio::sync::MutexGuard<'a, ()>, | ||
inner: &'a ArcSwap<T>, | ||
} | ||
|
||
impl<T> GuardArcSwap<T> { | ||
pub fn new(inner: T) -> Self { | ||
Self { | ||
inner: ArcSwap::new(Arc::new(inner)), | ||
guard: tokio::sync::Mutex::new(()), | ||
} | ||
} | ||
|
||
pub fn read(&self) -> Arc<T> { | ||
self.inner.load_full() | ||
} | ||
|
||
pub async fn write_guard(&self) -> Guard<'_, T> { | ||
Guard { | ||
_guard: self.guard.lock().await, | ||
inner: &self.inner, | ||
} | ||
} | ||
|
||
pub fn try_write_guard(&self) -> Result<Guard<'_, T>, TryLockError> { | ||
let guard = self.guard.try_lock()?; | ||
Ok(Guard { | ||
_guard: guard, | ||
inner: &self.inner, | ||
}) | ||
} | ||
} | ||
|
||
impl<T> Guard<'_, T> { | ||
pub fn read(&self) -> Arc<T> { | ||
self.inner.load_full() | ||
} | ||
|
||
pub fn write(&mut self, value: T) { | ||
self.inner.store(Arc::new(value)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cccc196
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
7477 tests run: 7090 passed, 0 failed, 387 skipped (full report)
Code coverage* (full report)
functions
:33.7% (8426 of 25029 functions)
lines
:49.2% (70493 of 143338 lines)
* collected from Rust tests only
cccc196 at 2025-01-16T17:53:45.448Z :recycle: