Python:仅在特定时间运行机器人的功能

问题描述 投票:0回答:1

我有一个必须连续运行的机器人,但我希望它只在工作日的工作时间调用一个特定的功能。有人建议我用 crontab 来做,但如果我没记错的话,这是不可能的,原因有两个:

  1. 我需要将我的机器人作为 docker 镜像运行(所以在 ALpine-Lynux 中)并且 crontab 不支持 lynux os

  2. 它只允许我每隔给定的秒/分钟/小时/天重复一个动作,并且没有可能的方式“说出来”(“如果我在工作日的工作时间连续运行该动作,否则只需等待下一个工作日上午 9 点")

这就是我正在构建的,我想知道等待函数的 2 个“版本”中哪个更好,但如果您知道任何最聪明的方法,我将不胜感激

def waiting_or_not():
    current_date = datetime.now(timezone('Europe/Rome'))
    need_to_wait = True
    if not isbday(current_date, holidays=Italy()) or current_date.hour > 18:
        next_run = get_next_working_day(current_date.replace(hour=9, minute=0, second=0) + timedelta(days=1))
    elif current_date.hour < 9:
        next_run = current_date.replace(hour=9, minute=0, second=0)
    else:
        need_to_wait = False
    if need_to_wait:
        seconds_to_wait = (next_run - current_date).total_seconds()
        # insert log
        wait(next_run)


def get_next_working_day(date_):
    while not isbday(date_):
        date_ += timedelta(days=1)
    return date_


def wait(next_run):
    '''
     I don't like this version at all. It seems to me ridiculous to "ask" continuously 
     the time. If it is friday evening after 18 and I need to wait until Monday morning,
     there will be billions of useless checks.
    '''
    current_date = datetime.now(timezone('Europe/Rome'))
    while current_date < next_run:
        current_date = datetime.now(timezone('Europe/Rome'))

def wait(next_run):
    '''
     I read sleep function is not precise and has big problems with huge numbers of seconds
    '''
    current_date = datetime.now(timezone('Europe/Rome'))
    time.sleep((next_run - current_date).total_seconds())
python cron bots sleep
1个回答
0
投票
  • 正如您所说,选项一将不断循环。 这将使您的 CPU 的一个核心占用率接近 100%, 浪费了大量的计算资源和能源。

  • 选项二更好,实际上是实现此目的的常用方法。 根据this question,睡眠的极限大约是 大约 400 万秒,也就是大约 46 天。 如果你真的担心那个,你可以使用类似这个版本的东西:

SLEEP_LIMIT = 1000000
def wait(next_run):
    seconds_till_next_run = (next_run - datetime.now(timezone('Europe/Rome'))).total_seconds()
    
    while seconds_till_next_run > SLEEP_LIMIT:
        time.sleep(SLEEP_LIMIT)
        seconds_till_next_run -= SLEEP_LIMIT
    if seconds_till_next_run > 0:
        time.sleep(seconds_till_next_run)
© www.soinside.com 2019 - 2024. All rights reserved.