使用aiohttp和aiojobs

时间:2018-02-01 08:10:13

标签: python aiohttp

我有一位经理来缓存一些用户设置。我希望每小时为非活动用户清理它(在我的示例中为10秒)。我尝试使用aiojobs。我在工作协程中产生了同样的工作。

from aiohttp import web
from aiojobs.aiohttp import setup, get_scheduler
import asyncio

async def cleanup(scheduler):
    await asyncio.sleep(10)
    print('do cleanup')
    await scheduler.spawn(cleanup(scheduler))

async def handler(request):
    if not request.app['init']:
        scheduler = get_scheduler(request)
        await scheduler.spawn(cleanup(scheduler))
        request.app['init'] = True
    return web.Response(text = 'ok')

def main():
    app = web.Application()
    app.router.add_get('/', handler)
    setup(app)
    app['init'] = False

    web.run_app(app, host='127.0.0.1', port = 8000)

main()

这是一个很好的解决方案吗?我应该创建自己的调度程序,因为我的工作与请求无关吗?

1 个答案:

答案 0 :(得分:0)

我希望某些后台任务与aiohttp Web服务器在同一循环中运行,甚至在任何HTTP请求到达之前也是如此。看来aiojobs帮不了我,所以我正在使用类似这样的东西。我使用的是janus队列,因为我的真实应用程序阻止了来自另一个线程的调用。我不太了解aiosync,所以这可能是盲人领先盲人。

import asyncio
from aiohttp import web
from aiojobs.aiohttp import setup
import janus


async def ticket_maker(q: janus.Queue):
    counter = 1
    while True:
        print(f'Made ticket {counter}')
        await q.async_q.put(counter)
        await asyncio.sleep(1)
        counter += 1


async def handler(request):
    q: janus.Queue = request.app.get('Q')
    ticket = await q.async_q.get()
    return web.Response(text=f'You got ticket {ticket}')


def main():
    q = janus.Queue()

    app = web.Application()
    asyncio.get_event_loop().create_task(ticket_maker(q))
    app.router.add_get('/', handler)
    app['Q'] = q
    setup(app)
    web.run_app(app, port=8080)


if __name__ == '__main__':
    main()