-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor(beatree): introduce a read transaction type #603
Conversation
This stack of pull requests is managed by Graphite. Learn more about stacking. |
ae57b58
to
1b81432
Compare
// be invalidated by any destructive changes. | ||
// | ||
// Once this guard drops, it will be safe to initiate a new read transaction. | ||
let read_tx_guard = read_transaction_latch.block_until_unique(); |
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.
I spent some time and I think I don't understand why this only blocks here but imediatelly released after we got the write. Why block then at all?
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.
It ensures that no new read transactions will be created until the write lock on self.shared
is released in any case.
It would be fine to hold read_tx_guard
until the end of this scope as well, of course. But not blocking would lead to a race, where we block_until_unique
but then a new read transaction is created by another thread before we can acquire shared.write()
.
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.
Sure, but why is it important to exclude the new readers only for the duration of this scope?
1b81432
to
1a981b5
Compare
1a981b5
to
e08ba49
Compare
ed25760
to
f96da7c
Compare
e08ba49
to
6c5cbac
Compare
*self.inner.read_transactions.lock() += 1; | ||
} | ||
|
||
fn block_until_unique(&self) -> MutexGuard<usize> { |
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.
this blocks until X gets unique.
What is X here?
// be invalidated by any destructive changes. | ||
// | ||
// Once this guard drops, it will be safe to initiate a new read transaction. | ||
let read_tx_guard = read_transaction_latch.block_until_unique(); |
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.
Sure, but why is it important to exclude the new readers only for the duration of this scope?
This introduces a basic read transaction type (not currently used) that is a first step towards enabling a safe asynchronous API for beatree. The immediate motivations are:
A less immediate but also useful goal is read transactions being used in
Session
s to enable parallel VMs to operate with fewer threads. This is groundwork for that future.Read transactions don't block commit or
finish_sync
(leaving room for "async sync" in the future), but do blocksync
from beginning. We can expect that sync will start at a natural moment where there are no outstanding read transactions (after a session is committed). When a sync will end is less predictable, and leaving some space for pipelining will be beneficial.