From 52ef0d66a145fd14714ddaec9b12248b99565dcf Mon Sep 17 00:00:00 2001 From: Sean Quah Date: Wed, 25 May 2022 14:24:13 +0100 Subject: [PATCH] Close `ijson` coroutines ourselves instead of letting the GC close them Hopefully this means that exceptions raised due to truncated JSON get a sensible logging context and stack. Signed-off-by: Sean Quah --- changelog.d/12875.bugfix | 1 + synapse/federation/transport/client.py | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 changelog.d/12875.bugfix diff --git a/changelog.d/12875.bugfix b/changelog.d/12875.bugfix new file mode 100644 index 000000000000..7b011e0f90e7 --- /dev/null +++ b/changelog.d/12875.bugfix @@ -0,0 +1 @@ +Explicitly close `ijson` coroutines once we are done with them, instead of leaving the garbage collector to close them. diff --git a/synapse/federation/transport/client.py b/synapse/federation/transport/client.py index 9ce06dfa28ba..20ebe9830140 100644 --- a/synapse/federation/transport/client.py +++ b/synapse/federation/transport/client.py @@ -1369,7 +1369,7 @@ def __init__(self, room_version: RoomVersion, v1_api: bool): # prefixing with `item.*`. prefix = "item." if v1_api else "" - self._coros = [ + self._coros: Generator[None, bytes, None] = [ ijson.items_coro( _event_list_parser(room_version, self._response.state), prefix + "state.item", @@ -1411,6 +1411,9 @@ def write(self, data: bytes) -> int: return len(data) def finish(self) -> SendJoinResponse: + for c in self._coros: + c.close() + if self._response.event_dict: self._response.event = make_event_from_dict( self._response.event_dict, self._room_version @@ -1430,7 +1433,7 @@ class _StateParser(ByteParser[StateRequestResponse]): def __init__(self, room_version: RoomVersion): self._response = StateRequestResponse([], []) self._room_version = room_version - self._coros = [ + self._coros: Generator[None, bytes, None] = [ ijson.items_coro( _event_list_parser(room_version, self._response.state), "pdus.item", @@ -1449,4 +1452,6 @@ def write(self, data: bytes) -> int: return len(data) def finish(self) -> StateRequestResponse: + for c in self._coros: + c.close() return self._response