1

I have such a simple code.

from aiohttp import web

async def hello(request):
    print('Start')
    for el in range(30000000):
        # Any expression
        1+el/10000*100000-4*234

    print('Stop')
    return web.Response(text="Hello, world")


app = web.Application()
app.add_routes([web.get('/', hello)])

web.run_app(app)

When I open my browser in http://0.0.0.0:8080/, I get the text "Start", and then after ~ 10 seconds I get the text "Stop". Then I open two pages http://0.0.0.0:8080/ at the same time. I expect to receive such texts within 10-11 seconds

'Start' #right now
'Start' #right now
'Stop' #in 10 sec
'Stop' #next sec

But i get (during 21 seconds)

'Start' #right now
'Stop' #in 10 sec
'Start' #at 11th sec
'Stop' #at 22th sec

What am I doing wrong?

guri
  • 11
  • 1

1 Answers1

1

You have a CPU-bound code:

for el in range(30000000):
    # Any expression
    1+el/10000*100000-4*234

It blocks event loop execution.

To solve the problem please move such code into thread pool executor.

The fixed example:

import asyncio
from aiohttp import web

def long_running_cpu_bound_task():
    for el in range(30000000):
        # Any expression
        1+el/10000*100000-4*234

async def hello(request):
    print('Start')
    await asyncio.get_event_loop().run_in_executor(
        None,
        long_running_cpu_bound_task)
    print('Stop')
    return web.Response(text="Hello, world")


app = web.Application()
app.add_routes([web.get('/', hello)])

web.run_app(app)
Andrew Svetlov
  • 16,730
  • 8
  • 66
  • 69