How to schedule a task in asyncio so it runs at a certain date?

前端 未结 1 1172
北海茫月
北海茫月 2020-12-30 07:21

My program is supposed to run 24/7 and i want to be able to run some tasks at a certain hour/date.

I have already tried to work with aiocron but it only supports sche

相关标签:
1条回答
  • 2020-12-30 07:31

    I have already tried to work with aiocron but it only supports scheduling functions (not coroutines)

    According to the examples at the link you provided, that does not appear to be the case. The functions decorated with @asyncio.coroutine are equivalent to coroutines defined with async def, and you can use them interchangeably.

    However, if you want to avoid aiocron, it is straightforward to use asyncio.sleep to postpone running a coroutine until an arbitrary point in time. For example:

    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
    

    Example usage:

    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()
    

    Note: Python versions before 3.8 didn't support sleeping intervals longer than 24 days, so wait_until had to work around the limitation. The original version of this answer defined it like this:

    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)
    

    The limitation was removed in Python 3.8 and the fix was backported to 3.6.7 and 3.7.1.

    0 讨论(0)
提交回复
热议问题