代码之家  ›  专栏  ›  技术社区  ›  sjw

Python异步restapi,响应依赖于CPU密集型计算。如何有效处理?[副本]

  •  1
  • sjw  · 技术社区  · 7 年前

    我已经使用 aiohttp ,下面提供了一个简化版本来说明我要解决的问题。

    API有两个端点-每个端点调用一个执行某些计算的函数。两者之间的区别在于,对于其中一个端点,计算时间为10秒,而对于另一个端点,计算时间仅为1秒。

    time.sleep() 电话)。

    import time
    from aiohttp import web
    
    
    def simple_calcs():
        time.sleep(1)  # Pretend this is the simple calculations
        return {'test': 123}
    
    def complex_calcs():
        time.sleep(10)  # Pretend this is the complex calculations
        return {'test': 456}
    
    
    routes = web.RouteTableDef()
    
    @routes.get('/simple_calcs')
    async def simple_calcs_handler(request):
        results = simple_calcs()
        return web.json_response(results)
    
    @routes.get('/complex_calcs')
    async def complex_calcs_handler(request):
        results = complex_calcs()
        return web.json_response(results)
    
    
    app = web.Application()
    app.add_routes(routes)
    web.run_app(app)
    

    我希望发生什么:

    如果我向较慢的端点发送请求,然后立即向较快的端点发送请求,我希望在较慢的计算仍在进行时,首先从较快的端点接收响应。

    实际发生的情况:

    我在过去的几个小时里一直在转圈,仔细阅读 asyncio multiprocessing ,但找不到任何可以解决我问题的方法。也许我需要花一点时间来研究这个领域,以获得更好的理解,但希望我能得到一个正确的方向朝着理想的结果推动。

    1 回复  |  直到 7 年前
        1
  •  3
  •   Andrew Svetlov    7 年前

    在asyncio中应避免任何阻塞IO调用。

    基本上 time.sleep(10)

    要解决这个问题,请使用 loop.run_in_executor() 电话:

    async def complex_calcs():
        loop = asyncio.get_event_loop()
        loop.run_in_executor(None, time.sleep, 10)  # Pretend this is the complex calculations
        return {'test': 456}