APScheduler 错过的作业在进程重新启动时不会运行

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

我正在进行一项实验,我将一个作业设置为未来 30 秒,终止调度程序进程,等待一两分钟,然后重新启动它,期望错过的作业将被执行为一旦该过程再次开始。 redis 服务器始终保持开启状态,我通过在 redis-cli 中查找密钥来确认该状态已持续存在。我还使用他们的 SQLAlchemy 解决方案重新创建了同样的问题。

但是,重新启动后,该作业根本没有执行,所以它仍然被错过。在生产中使用它之前,我需要弄清楚如何恢复错过的工作。

这是脚本的内容cron,以便您可以重现。任何帮助表示赞赏。我假设我有一些配置错误或者可能误解了这个系统的功能。

clock.py

我还有来自redis的序列化作业的内容

# apscheduler version 3.10.4

import logging
import os
import sys
import urllib.parse

from apscheduler.executors.pool import ThreadPoolExecutor
from apscheduler.jobstores.redis import RedisJobStore
from apscheduler.schedulers.blocking import BlockingScheduler
from pytz import utc

# Without this, the paths to `snake` modules etc. will not be located.
sys.path.append(os.path.join(os.path.dirname(__file__), "mysite"))

import django

django.setup()

from django.conf import settings

logging.basicConfig()
# The string "apscheduler" is necessary for logs to give good output.
logging.getLogger('apscheduler').setLevel(logging.DEBUG)


# WEB_CONCURRENCY is set by Heroku dynos automatically
number_of_cores = int(os.environ.get("WEB_CONCURRENCY", os.cpu_count() or 1))


parsed_redis_url = urllib.parse.urlparse(settings.REDIS_URL)
redis_job_store = RedisJobStore(
    host=parsed_redis_url.hostname,
    port=parsed_redis_url.port,
    password=parsed_redis_url.password,
    db=settings.CACHE_REDIS_DB,
    ssl=True if parsed_redis_url.scheme == "rediss" else False,
    ssl_cert_reqs=None,
)

# ==========
## APScheduler Configuration

job_defaults = {
    'max_instances': 1,
    'misfire_grace_time': 60 * 50
    'coalesce': True
}

executors = {'default': ThreadPoolExecutor(number_of_cores)}


jobstores = {
    'default': redis_job_store,
}

scheduler = BlockingScheduler(
    executors=executors,
    logger=logging,
    job_defaults=job_defaults,
    timezone=utc,
    jobstores=jobstores,
)


@scheduler.scheduled_job('cron', hour=20, minute=38, second=40, name="print_ongoing", id="1")
def print_ongoing():
    from time import sleep

    from django.utils.crypto import get_random_string

    unique_id = get_random_string(length=4)
    s = 0
    while s < 1000:
        print(unique_id)
        s += 1
        sleep(1)


scheduler.start()

我认为问题可能只是你正在使用合并:
apscheduler
1个回答
0
投票
如果为作业启用了合并,并且调度程序看到该作业的一个或多个排队执行,则只会触发一次。对于“绕过”运行,不会发送失火事件。

https://apscheduler.readthedocs.io/en/3.x/userguide.html#missed-job-executions-and-coalescing

© www.soinside.com 2019 - 2024. All rights reserved.