在使用aiohttp编写的Web应用程序中,我有2个端点。首先是启动异步任务,这是无限循环。第二个旨在取消某些任务。由于异步任务没有任何ID概念,我有点困惑。 是否可以在数据库中保存任务的某些标识符? 是这样做的正确方法,还是lib已经为此类问题提供了解决方案?
from aiohttp import web
import asyncio
import json
async def coro(frequency):
while True:
print('Infinite loop iteration')
await asyncio.sleep(frequency)
def start_task(request):
event_loop = asyncio.get_event_loop()
task = event_loop.create_task(coro())
# save some identifier of the task in the database to find it later
response = dict()
return web.json_response(json.dumps(response))
def stop_task(request):
task = None # here i must get a certain task outta event loop
task.cancel()
response = dict()
return web.json_response(json.dumps(response))
感谢您的帮助!
答案 0 :(得分:0)
您可以生成简单的单调递增的数字ID,并具有将ID映射到任务实例的全局字典。协程完成后,映射将被删除。例如(未试用):
import asyncio, itertools
_next_id = itertools.count().__next__
_tasks = {}
def make_task(corofn, *coroargs):
task_id = _next_id()
async def wrapped_coro():
try:
return await corofn(*coroargs)
finally:
del _tasks[task_id]
task = asyncio.create_task(wrapped_coro())
_tasks[task_id] = task
return task_id, task
def get_task(task_id):
return _tasks[task_id]
然后您可以在start_task
和stop_task
中使用它:
def start_task(request):
task_id, _ = make_task(coro)
response = {'task_id': task_id}
return web.json_response(json.dumps(response))
def stop_task(request):
task_id = json.loads(await request.text())['task_id']
task = get_task(task_id)
task.cancel()
response = {}
return web.json_response(json.dumps(response))