asyncio questions

Frank Millman frank at chagford.com
Fri Jan 27 07:14:35 EST 2023


On 2023-01-26 7:16 PM, Dieter Maurer wrote:
> Frank Millman wrote at 2023-1-26 12:12 +0200:
>> I have written a simple HTTP server using asyncio. It works, but I don't
>> always understand how it works, so I was pleased that Python 3.11
>> introduced some new high-level concepts that hide the gory details. I
>> want to refactor my code to use these concepts, but I am not finding it
>> easy.
>>
>> In simple terms my main loop looked like this -
>>
>>      loop = asyncio.get_event_loop()
>>      server = loop.run_until_complete(
>>          asyncio.start_server(handle_client, host, port))
>>      loop.run_until_complete(setup_companies())
>>      session_check = asyncio.ensure_future(
>>          check_sessions())  # start background task
>>      print('Press Ctrl+C to stop')
>>      try:
>>          loop.run_forever()
>>      except KeyboardInterrupt:
>>          print()
>>      finally:
>>          session_check.cancel()  # tell session_check to stop running
>>          loop.run_until_complete(asyncio.wait([session_check]))
>>          server.close()
>>          loop.stop()
> 
> Why does your code uses several `loop.run*` calls?
> 
> In fact, I would define a single coroutine and run that
> with `asyncio.run`.
> This way, the coroutine can use all `asyncio` features,
> including `loop.create_task`.

You are right, Dieter. The function that I showed above is a normal 
function, not an async one. There was no particular reason for this - I 
must have got it working like that at some point in the past, and 'if it 
ain't broke ...'

I have changed it to async, which I call with 'asyncio.run'. It now 
looks like this -

     server = await asyncio.start_server(handle_client, host, port)
     await setup_companies()
     session_check = asyncio.create_task(
         check_sessions())  # start background task

     print('Press Ctrl+C to stop')

     try:
         await server.serve_forever()
     except asyncio.CancelledError:
         pass
     finally:
         session_check.cancel()  # tell session_check to stop running
         await asyncio.wait([session_check])
         server.close()

It works exactly the same as before, and it is now much neater.

Thanks for the input.

Frank



More information about the Python-list mailing list