Fix bug where we wedge media plugins if clients disconnect early (#13660)

We incorrectly didn't use the returned `Responder` if the client had
disconnected, which meant that the resource used by the Responder
wasn't correctly released.

In particular, this exhausted the thread pools so that *all* requests
timed out.
This commit is contained in:
Erik Johnston 2022-08-30 12:17:48 +01:00 committed by GitHub
parent 303b40b988
commit 1c26acd815
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 22 additions and 19 deletions

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

@ -0,0 +1 @@
Fix bug where we wedge media plugins if clients disconnect early. Introduced in v1.22.0.

View File

@ -254,30 +254,32 @@ async def respond_with_responder(
file_size: Size in bytes of the media. If not known it should be None file_size: Size in bytes of the media. If not known it should be None
upload_name: The name of the requested file, if any. upload_name: The name of the requested file, if any.
""" """
if request._disconnected:
logger.warning(
"Not sending response to request %s, already disconnected.", request
)
return
if not responder: if not responder:
respond_404(request) respond_404(request)
return return
logger.debug("Responding to media request with responder %s", responder) # If we have a responder we *must* use it as a context manager.
add_file_headers(request, media_type, file_size, upload_name) with responder:
try: if request._disconnected:
with responder: logger.warning(
await responder.write_to_consumer(request) "Not sending response to request %s, already disconnected.", request
except Exception as e: )
# The majority of the time this will be due to the client having gone return
# away. Unfortunately, Twisted simply throws a generic exception at us
# in that case.
logger.warning("Failed to write to consumer: %s %s", type(e), e)
# Unregister the producer, if it has one, so Twisted doesn't complain logger.debug("Responding to media request with responder %s", responder)
if request.producer: add_file_headers(request, media_type, file_size, upload_name)
request.unregisterProducer() try:
await responder.write_to_consumer(request)
except Exception as e:
# The majority of the time this will be due to the client having gone
# away. Unfortunately, Twisted simply throws a generic exception at us
# in that case.
logger.warning("Failed to write to consumer: %s %s", type(e), e)
# Unregister the producer, if it has one, so Twisted doesn't complain
if request.producer:
request.unregisterProducer()
finish_request(request) finish_request(request)