I have a falcon API (WSGI) that I wrote that needs to be as fast as possible.
At one part of the code I have the respond that I need to send to the client, but I have a datalake where I send all of responses + some more calculation results using kafka. I want to separate the extra calculations + the send to kafka as the client does not need wait for it and it takes more time then I want it to.
Is there a way to do it in Falcon without handling the threads by myself like this:
class Compute(Thread):
def __init__(self, request):
Thread.__init__(self)
self.request = request
def run(self):
print("start")
time.sleep(5)
print(self.request)
print("done")
class FalconApi
def on_post(self, request: falcon.Request, response: falcon.Response):
thread_a = Compute(request.__copy__())
thread_a.start()
I run the API using gunicorn so I thought maybe I could use the hook post_request but I can't seem to be able to get the response data in the hook. I also tried using asyncio but it seems like it does not like when I do use it because my app is WSGI.
My async code:
class FalconApi
@staticmethod
def http_post(response: falcon.Response) -> None:
requests.post(consts.ENDPOINT, headers=response.headers, data=json.dumps(response.data))
async def http_post_async(self, response: falcon.Response) -> None:
await asyncio.to_thread(self.http_post, response)
def on_post(self, request: falcon.Request, response: falcon.Response):
self.http_post_async(response)
and the error that I got: RuntimeWarning: coroutine 'http_post_async' was never awaited
and when I changed it to:
async def on_post(self, request: falcon.Request, response: falcon.Response):
self.http_post_async(response)
I got: TypeError: The <bound methodon_post of object at 0x7f7cf0c4ffd0>> responder must be a regular synchronous method to be used with a WSGI app.
This is what I ended up doing which worked for me.
I added a
gunicornhookpost_requestand I added the response I want to post process to thefalcon.request.envattribute and then I extracted it in the hook.My code looks something like:
api.py:
hooks.py:
and then I run it using
gunicorn -c hooks.py