You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm implementing a layer of a database, and I'm thinking about relying on a specific corner case of the read_biased setter. In this situation, the DB is going to flush a bunch of cached writes to disk, but I want to allow readers to view the cached data during that time, while simultaneously have writers queue up on the lock so the cache doesn't mutate during the flush.
Specific code if interested
classSomeCustomDB:
lock=tricycle.RWLock()
...
@contextlib.asynccontextmanagerasyncdefwrite_tx(self):
asyncwithself.lock.write_locked():
self.lock.read_biased=Falsetoken=self.checkpoint()
try:
yieldexceptBaseExceptionase:
self.restore(token)
raiseefinally:
# need opportunity to flush even after rollback# previous chained writes may have modified the cacheifself.lock.statistics().writers_waiting==0:
self.lock.read_biased=Truewithtrio.CancelScope(shield=True):
awaitself.aflush()
else:
awaittrio.lowlevel.cancel_shielded_checkpoint()
I thought that setting self.lock.read_biased = True while holding the write lock would just change the behavior after the lock is dropped, but it has the effect of calling _wake_all_readers, meaning a bunch of readers think they've aquired the lock and start running. But any new readers during the flush will block when acquiring the lock, because _writer is not None so acquire_nowait would raise WouldBlock.
This is all a bit weird, but it happens to be exactly what I want. I could possibly achieve my goal by dropping the lock, setting read_biased = True outside the lock, and re-acquiring it for read to do my flush, so I'm good either way, but I wanted to point out this edge case in the event you wanted to either canonize it or fix it.
The text was updated successfully, but these errors were encountered:
I'm implementing a layer of a database, and I'm thinking about relying on a specific corner case of the
read_biased
setter. In this situation, the DB is going to flush a bunch of cached writes to disk, but I want to allow readers to view the cached data during that time, while simultaneously have writers queue up on the lock so the cache doesn't mutate during the flush.Specific code if interested
I thought that setting
self.lock.read_biased = True
while holding the write lock would just change the behavior after the lock is dropped, but it has the effect of calling_wake_all_readers
, meaning a bunch of readers think they've aquired the lock and start running. But any new readers during the flush will block when acquiring the lock, because_writer is not None
soacquire_nowait
would raiseWouldBlock
.This is all a bit weird, but it happens to be exactly what I want. I could possibly achieve my goal by dropping the lock, setting
read_biased = True
outside the lock, and re-acquiring it for read to do my flush, so I'm good either way, but I wanted to point out this edge case in the event you wanted to either canonize it or fix it.The text was updated successfully, but these errors were encountered: