web-dev-qa-db-ja.com

特定の日付に実行されるようにasyncioでタスクをスケジュールするにはどうすればよいですか?

私のプログラムは24時間年中無休で実行されることになっていますが、特定の時間/日付でいくつかのタスクを実行できるようにしたいと考えています。

私はすでに aiocron で作業しようとしましたが、スケジューリング関数(コルーチンではない)のみをサポートしており、それは本当に良いライブラリではないことを読みました。私のプログラムは、スケジュールしたいすべてのタスクではないにしてもほとんどがコルーチンに組み込まれているように構築されています。

そのような種類のタスクスケジューリングを可能にする他のライブラリはありますか?

または、そうでない場合は、コルーチンをワープして通常の機能を実行する方法はありますか?

7
Laikar

私はすでにaiocronを使用しようとしましたが、スケジューリング機能のみをサポートしています(コルーチンはサポートしていません)

あなたが提供した link の例によると、そうではないようです。 @asyncio.coroutineで装飾された関数は、async defで定義されたコルーチンと同等であり、それらを交換して使用できます。

ただし、aiocronを回避したい場合は、asyncio.sleepを使用して、任意の時点までコルーチンの実行を延期するのが合理的に簡単です。例えば:

import asyncio, datetime

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

async def run_at(dt, coro):
    await wait_for(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()
4
user4815162342