question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Detect/handle closed client connections

See original GitHub issue

It appears like starlette does not cancel inner processing for when a client disconnects.

With the following code it will keep on fetching from the remote, although the client has disconnected already, e.g. when cancelling a curl call.

@app.route(…)
async def foo(request):
    …
    if content_type.startswith("video/"):
        bytes_total = req.headers["Content-Length"]
        logger.info("Streaming {} bytes...", bytes_total)

        async def generator(bytes_total):
            import aiohttp
            async with aiohttp.ClientSession() as session:
                chunk = 0
                chunk_size = 102400
                bytes_read = 0
                async with session.request(method, str(url), chunked=chunk_size) as resp:
                    async for data, end_of_http_chunk in resp.content.iter_chunks():
                        chunk += 1
                        bytes_read += chunk_size
                        logger.info("chunk {} {}/{}", chunk, bytes_read, bytes_total)
                        yield data
        return StreamingResponse(generator(bytes_total), media_type=content_type)

It might be useful if the handler could be notified of this, in case it wants to handle this, but in general I think a late middleware, responsible for sending could handle this maybe?!

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:1
  • Comments:8 (8 by maintainers)

github_iconTop GitHub Comments

2reactions
tomchristiecommented, Jan 14, 2019

I think the following would also do the trick, for a non-blocking receive: message = await asyncio.wait_for(receive, timeout=0).

1reaction
tomchristiecommented, Jan 3, 2019

I’m trying to implement SSE manually by returning a StreamingResponse, but the generator cannot know when the client disconnects and will keep sending events (although to a no-op) indefinitely.

Right. The thing is that the disconnect needs to be handled in an event driven way, rather than raising an exception on send().

I’ve initially tried await receive(), where a disconnect message would appear, but that might block without any message(s)

Sure, so I think what you’d need is something like:

done, pending = await asyncio.wait([receive, response.content.read], return_when=FIRST_COMPLETED)
task = done[0]
if task is receive:
    message = task.result()
else:
    data = task.result()

Not wild about how akward it is to do a await either this thing or that thing and switch on either, but there we are.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Handling abandoned/disconnected Sockets - Stack Overflow
the connections will be closed (assuming TCP). You will know that those connections are dead. Exactly how depends on your coding.
Read more >
Action 2: investigate closed client connection - IBM
2610-204 The client connection is closed due to incorrect message (incorrect message code). Diagnosis: The 2610-204 message is logged by the RMC subsystem, ......
Read more >
what is TCP Half Open Connection and TCP half closed ...
TCP has a vulnerability in that the final FIN packet sent to a client can be potentially dropped by routers/networks resulting in a...
Read more >
How to detect when the client closes the connection?
We need a separate process that does nothing else but checking whether a connection has been closed by the client (of course, this...
Read more >
Managing Client Connections - Vertica
This section explains how you can control the way clients connect to your database. Vertica gives you several settings to control client connections:....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found