#async responses (not python async, the web-related async)

1 messages · Page 1 of 1 (latest)

gaunt vine
#

As title- I'd like to deliver a response to a request rapidly, but continue in the route handler.
I could just use asyncio.create_task for the remainder of the function but I'm wondering if litestar has a way to do this. Yield, perhaps?

ashen anvil
#

I understand you want to send a response, then do some processing in the handler, I am not sure of that, I would just pass the relevant stuff to the background task

brazen summit
#

Yield is an interesting idea 💡

<@&919261960921546815> ?

#

You can use background tasks and event emitters

#

Two builtin patterns

gaunt vine
#

I have to ask what the difference between a backgroundtask and just a regular o'l asyncio.Task is

ashen anvil
#

one reason I know is background task automatically takes care of sync or async, if its asyncio.task you have to do it yourself

gaunt vine
#

what like it throws things in a thread if they're sync

#

event emitters seem like a decent way to go about it though but I'm on 1.0

#

and yeah I think yield would be a pretty decent way to do this as a higher level API
particularily for async responders where they're basically just

async def route
  yield response
  <code>```
ashen anvil
gaunt vine
#

I guess this precludes the "need to keep a reference around to the task object to avoid getting GC'd" problem

ashen anvil
gaunt vine
#

Another possible way to do it is


async def route
  try:
    return whatever
  finally:
    other stuff```
but I'm not entirely sure how that handles a lot of situations
brazen summit
# gaunt vine I have to ask what the difference between a backgroundtask and just a regular o'...

They are unrelated.

While it's a similar concept to an extent in a very abstract way the mechanism is different. An asyncio task is executed in it's own "Async thread", whereas a background task is simply a wrapper around a callable or a chain of callables that is awaited by the response after the response instance itself finishes send the response. It's a mechanism we inherited from Starlette and is also shared by FastAPI.

gaunt vine
#

oh so internally it's

send response()
background_task()

?

brazen summit
#

Pretty much

#

You can actually look 😁

gaunt vine
#

entirely superpossible

obtuse peak
#

Hmm, interesting idea. I’m not sure if the complexity of adding support is worth it. Would it just be syntactic sugar for after_request? What should happen if there are multiple yields?

gaunt vine
#

unless you're doing some sort of streaming response I would think multi-yield should probably just error

gaunt vine
#

it works well but style-wise it's kind of cumbersome

obtuse peak
gaunt vine
#

I don't think this one fits-
The just of it is like this:

Async def route(data):
If early exit:
Return
Resource= Queue.get()
Resource()
Return something
Finally:
Resource.close()

#

The resource is both expensive to create and destroy, as well as have open so I have a little task running that keeps a queue populated with them as needed

obtuse peak
#

I don’t see anything there that can’t be done in a dependency.

gaunt vine
#

can a dep have access to the request?

obtuse peak
#

Yep, same as handlers by using the request kwarg in the dependency callable signature

gaunt vine
#

Neat I guess that peg does fit into this hole

trail tide
#

We have enough of those already

#

And it sounds like background tasks are just what @gaunt vine is asking for, since I can't make out any difference in usability between those and the suggested solution with yield

ashen anvil