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.

Ability to execute logic after the response is fully streamed

See original GitHub issue

Right now, the middleware method process_response can be used to post-process responses after they are routed and handled by responders.

However, in case response body is a stream, one may want to execute logic when the stream iterable is exausted. We are already wrapping req.stream in some cases, so we could extend this to wrap .close() with code to execute the relevant method (finalize_response?) from middlewares added to the API.

Use cases could include cleaning up resources that were used to stream the response, such as releasing database connections back to the pool.

Issue Analytics

  • State:open
  • Created 4 years ago
  • Comments:7 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
vytas7commented, Jul 7, 2020

Doh, sorry… My bad 😬 Anyway, finalize_response would very obviously be executed after everything else in the request-response cycle.

0reactions
numberoverzerocommented, Jul 7, 2022

+1 I’d love to have a way to run cleanup logic after the stream has been consumed, or after the stream raises, or the connection is closed.

I’m using the following to wrap the response stream and execute a callback when read raises or close is called[0].

import io

class StreamWithCallback(io.BufferedIOBase):
    def __init__(self, wrapped: io.BufferedIOBase, callback=None) -> None:
        self._wrapped = wrapped
        self._callback = callback

    def close(self):
        if self._wrapped:
            try:
                self._wrapped.close()
                self._wrapped = None
            finally:
                if self._callback:
                    self._callback()

    def read(self, n: int) -> bytes:
        try:
            return self._wrapped.read(n)
        except:
            self.close()
            raise

And I’m using it like so:

def on_get(self, req: falcon.Request, resp: falcon.Response, id: str) -> None:
    stream = self.controller.get_read_stream(id)
    def cleanup():
        self.controller.remove_by_id(id)
    resp.status = falcon.HTTP_200
    resp.stream = ReadWithCallback(stream, cleanup)

[0] Most wsgi frameworks should call close on the stream, although I only verified this for gunicorn sync threads.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Getting InputStream with RestTemplate - java - Stack Overflow
RELEASE has a ResourceHttpMessageConverter that has a boolean supportsReadStreaming , which if set, and the response type is InputStreamResource ...
Read more >
What is a smart contract and how does it work? - TechTarget
A smart contract is a decentralized application that executes business logic in response to events.
Read more >
Creating a dialog - IBM Cloud Docs
To add a Connect to human agent response type, complete the following steps: From the dialog node where you want to add the...
Read more >
Exactly-Once Semantics Are Possible: Here's How Kafka Does It
Exactly-once stream processing is simply the ability to execute a read-process-write operation exactly one time. In this case, “getting the ...
Read more >
Use Custom Process Actions with code (Microsoft Dataverse)
Extend Custom Process Actions; Required permissions; Watch out for ... be executed outside of Dataverse using Power Automate, Logic Apps, ...
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