小编典典

如何安排任务在asyncio中使其在特定日期运行?

python

我的程序应该运行24/7,我希望能够在某个小时/日期运行某些任务。

我已经尝试使用aiocron,但是它仅支持调度功能(不支持协程),并且我读到它并不是一个很好的库。我的程序是构建的,因此我要调度的大多数(如果不是全部)任务都是在协程中构建的。

是否有其他库可以进行此类任务调度?

否则,是否有任何使协程变形以使它们运行正常的方式?


阅读 225

收藏
2021-01-20

共1个答案

小编典典

我已经尝试过使用aiocron,但它仅支持调度功能(不支持协程)

根据您提供的链接上的示例,情况似乎并非如此。装饰的功能@asyncio.coroutine等同于用定义的协程async def,您可以互换使用它们。

但是,如果要避免使用Aiocron,可以直接将asyncio.sleep协程推迟运行到任意时间点。例如:

import asyncio, datetime

async def wait_until(dt):
    # sleep until the specified datetime
    now = datetime.datetime.now()
    await asyncio.sleep((dt - now).total_seconds())

async def run_at(dt, coro):
    await wait_until(dt)
    return await coro

用法示例:

async def hello():
    print('hello')

loop = asyncio.get_event_loop()
# print hello ten years after this answer was written
loop.create_task(run_at(datetime.datetime(2028, 7, 11, 23, 36),
                        hello()))
loop.run_forever()

注意:3.8之前的Python版本不支持超过24天的睡眠间隔,因此wait_until必须解决该限制。该答案的原始版本定义如下:

async def wait_until(dt):
    # sleep until the specified datetime
    while True:
        now = datetime.datetime.now()
        remaining = (dt - now).total_seconds()
        if remaining < 86400:
            break
        # pre-3.7.1 asyncio doesn't like long sleeps, so don't sleep
        # for more than one day at a time
        await asyncio.sleep(86400)
    await asyncio.sleep(remaining)

该限制已在Python
3.8中删除,并且修复程序已反向移植到3.6.7和3.7.1。

2021-01-20