Merge pull request #3723 from matrix-org/rav/fix_logcontext_disaster

Fix exceptions when a connection is closed before we read the headers
This commit is contained in:
Amber Brown 2018-08-21 03:47:52 +10:00 committed by GitHub
commit 23d7e63a4a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 18 additions and 3 deletions

1
changelog.d/3723.bugfix Normal file
View File

@ -0,0 +1 @@
Fix bug in v0.33.3rc1 which caused infinite loops and OOMs

View File

@ -182,7 +182,7 @@ class SynapseRequest(Request):
# the client disconnects. # the client disconnects.
with PreserveLoggingContext(self.logcontext): with PreserveLoggingContext(self.logcontext):
logger.warn( logger.warn(
"Error processing request: %s %s", reason.type, reason.value, "Error processing request %r: %s %s", self, reason.type, reason.value,
) )
if not self._is_processing: if not self._is_processing:
@ -219,6 +219,12 @@ class SynapseRequest(Request):
"""Log the completion of this request and update the metrics """Log the completion of this request and update the metrics
""" """
if self.logcontext is None:
# this can happen if the connection closed before we read the
# headers (so render was never called). In that case we'll already
# have logged a warning, so just bail out.
return
usage = self.logcontext.get_resource_usage() usage = self.logcontext.get_resource_usage()
if self._processing_finished_time is None: if self._processing_finished_time is None:

View File

@ -385,7 +385,13 @@ class LoggingContextFilter(logging.Filter):
context = LoggingContext.current_context() context = LoggingContext.current_context()
for key, value in self.defaults.items(): for key, value in self.defaults.items():
setattr(record, key, value) setattr(record, key, value)
# context should never be None, but if it somehow ends up being, then
# we end up in a death spiral of infinite loops, so let's check, for
# robustness' sake.
if context is not None:
context.copy_to(record) context.copy_to(record)
return True return True
@ -396,7 +402,9 @@ class PreserveLoggingContext(object):
__slots__ = ["current_context", "new_context", "has_parent"] __slots__ = ["current_context", "new_context", "has_parent"]
def __init__(self, new_context=LoggingContext.sentinel): def __init__(self, new_context=None):
if new_context is None:
new_context = LoggingContext.sentinel
self.new_context = new_context self.new_context = new_context
def __enter__(self): def __enter__(self):