Python Forum
How to use asyncio run_forever to continuously handle requests
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to use asyncio run_forever to continuously handle requests
#1
Hi all,

I have a Python script that handles a continuous stream of requests, processing them using asyncio.
I find that the script hangs at times and stops handling new requests.
I believe I found the issue was that the parent task was a weak reference and possibly garage collected before it was completed.

I fixed that issue, but now the code handles only 1 request, then does not respond afterwards to a new request.

The key part of the script is
    import asyncio
    from sums_classes import SUMS_Requests
    ....

    sums_loop and sums_sock defined here

   ...

    def _handle_ahandle_throws(task: asyncio.Task):
        try:
            task.result()
            return task
        except asyncio.CancelledError:
            log.writeInfo(['CancelledError exception raised in ahandle task = %r', task])
            pass
        ...

    async def sums_server():
        conn, client_addr = await sums_loop.sock_accept(sums_sock)            <---get conn from socket
        sr = SUMS_Requests(sums_loop, log)                                               <---instantiate class SUMS_Requests
        sums_task = sums_loop.create_task(sr.ahandle(conn))                       <---handle request
        all_tasks.add(sums_task)
        sums_task.add_done_callback(_handle_ahandle_throws)                    <---callback
        log.writeInfo(['sums_task done = ' + str(sums_task.done())])

    log.writeInfo(['Creating task to await for asyncio coroutine sum server...   serving on ' + str(sums_sock)])
    sums_main_task = sums_loop.create_task(sum_server())                              <---save parent task as strong reference
    sums_main_task.add_done_callback(_handle_ahandle_throws)                      <---callback
    log.writeInfo(['sums main task done = ' + str(sums_main_task.done())])

    try:
       sums_loop.run_forever()                         <--- should handle continuous requests
    except KeyboardInterrupt:
        log.writeInfo(['Received SIGINT from stop script.... shutting down now    pid = ' + str(pid)])
        sums_loop.close()
        sums_sock.shutdown(socket.SHUT_RDWR)
        sums_sock.close()
        raise KeyboardInterrupt
    finally:
      ....
The script runs in Python 3.11.4 on RedHat 8.8, my comments for readability in this thread start with <---

I added sums_main_task to make the first Task a strong reference, the purpose of which is to create a Task to run the async method sums_server.
Inside sums_server I create a 2nd Task, called sums_task, which calls the method ahandle in class SUMS_Request, which does all the work.

Once ahandle completes (returning True for the final step), the Task sums_task is completed, and the callback _handle_ahandle_throws is called.
This sequence works fine for one request.

When a second request is sent to the script, no log entries appear in the log file and the code doesn't respond.
I was hoping that once the callback invoked by the child Task sums_task was done, control would go back to sums_server and a new request
would be handled.

I suspect that once the callback is invoked by the child and then parent Tasks, the event loop is completed, but control is not passed back to either
the current loop, or a new one. Hence my problem of the script processing only one request.

What's the correct sequence for event loops & Tasks to have run_forever continuously handle new requests as them arrive ?

Thanks,

--Ed
Reply
#2
Instead of this:
 try:
    sums_loop.run_forever()                         <--- should handle continuous requests
 except KeyboardInterrupt:
     log.writeInfo(['Received SIGINT from stop script.... shutting down now    pid = ' + str(pid)])
     sums_loop.close()
     sums_sock.shutdown(socket.SHUT_RDWR)
     sums_sock.close()
     raise KeyboardInterrupt
 finally:
I would do this:
 try:
    sums_loop.run_forever()                         <--- should handle continuous requests
finally:
     log.writeInfo(['Received SIGINT from stop script.... shutting down now    pid = ' + str(pid)])
     sums_loop.close()
     sums_sock.shutdown(socket.SHUT_RDWR)
     sums_sock.close()
The problem is probably in sums_loop.run_forever(). I don't think you are showing any of the relevant code.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  How to continuously receive messages until specified to stop using Bleak jacobbreen25 3 2,209 Dec-28-2022, 04:25 PM
Last Post: jacobbreen25
  How to listen to clipboard content change without polling the clipboard continuously? edgelord 0 2,509 Nov-27-2020, 06:07 AM
Last Post: edgelord
  Custom logging handler looping continuously linuxaddikt 0 1,809 Mar-12-2020, 06:58 PM
Last Post: linuxaddikt
  Continuously iterating through a csv file ExplodingCoyote 2 3,720 Feb-26-2020, 07:56 AM
Last Post: DeaD_EyE
  How to Continuously Remove Letters from Words ZQ12 1 2,586 Nov-23-2019, 05:31 PM
Last Post: perfringo

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020