Fix long-standing bug where ReadWriteLock could drop logging contexts (#10993)

Use `PreserveLoggingContext()` to ensure that logging contexts are not
lost when exiting a read/write lock.

When exiting a read/write lock, callbacks on a `Deferred` are triggered
as a signal to any waiting coroutines. Any waiting coroutine that
becomes runnable is likely to follow the Synapse logging context rules
and will restore its own logging context, then either run to completion
or await another `Deferred`, resetting the logging context in the
process.
This commit is contained in:
Sean Quah 2021-10-08 12:27:16 +01:00 committed by GitHub
parent bb228f3523
commit 49a683d871
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 5 additions and 2 deletions

1
changelog.d/10993.misc Normal file
View File

@ -0,0 +1 @@
Fix a long-standing bug where `ReadWriteLock`s could drop logging contexts on exit.

View File

@ -438,7 +438,8 @@ class ReadWriteLock:
try: try:
yield yield
finally: finally:
new_defer.callback(None) with PreserveLoggingContext():
new_defer.callback(None)
self.key_to_current_readers.get(key, set()).discard(new_defer) self.key_to_current_readers.get(key, set()).discard(new_defer)
return _ctx_manager() return _ctx_manager()
@ -466,7 +467,8 @@ class ReadWriteLock:
try: try:
yield yield
finally: finally:
new_defer.callback(None) with PreserveLoggingContext():
new_defer.callback(None)
if self.key_to_current_writer[key] == new_defer: if self.key_to_current_writer[key] == new_defer:
self.key_to_current_writer.pop(key) self.key_to_current_writer.pop(key)