【问题标题】:Which of the combined triggers caused job execution in apscheduler?哪个组合触发器导致在 apscheduler 中执行作业?
【发布时间】:2019-09-08 08:03:46
【问题描述】:

TL;DR:combining triggers 在 APScheduler 中时,是否有可能知道是哪个原始触发器导致作业执行?

更长的故事:我正在尝试运行通过 SNMP 从设备获取数据的任务。有些任务每 2 分钟运行一次,有些每 5 分钟运行一次,有些每 10 分钟运行一次……但是当间隔对齐时,出于性能原因,将这些任务合并到一个查询中很重要。

解决此问题的一种方法是实现自定义executor,但这似乎有点复杂。将任务组合在一个作业中似乎更容易,该作业在任何间隔上运行 - 但是,我需要知道 哪个 间隔触发了作业执行。有没有办法获取这些信息?

小例子:

from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.triggers.combining import OrTrigger
from apscheduler.triggers.interval import IntervalTrigger
import logging


logging.basicConfig(format='%(asctime)s | %(levelname)s | %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S', level=logging.DEBUG)
log = logging.getLogger("{}.{}".format(__name__, "base"))


def test_func(*args, **kwargs):
    log.warn("Which interval(s) caused this job to execute? I only got args: {}, kwargs: {}".format(args, kwargs))


if __name__ == "__main__":
    scheduler = BlockingScheduler()

    # apply config to scheduler:
    intervals = [10, 15, 50]
    trigger = OrTrigger([IntervalTrigger(seconds=sec) for sec in intervals])
    scheduler.add_job(test_func, trigger=trigger, kwargs={"a": 123, "b": 345})

    try:
        scheduler.start()
    except KeyboardInterrupt:
        log.info("Got exit signal, exiting.")

输出:

2019-09-08 09:57:59 | INFO | Adding job tentatively -- it will be properly scheduled when the scheduler starts
2019-09-08 09:57:59 | INFO | Added job "test_func" to job store "default"
2019-09-08 09:57:59 | INFO | Scheduler started
2019-09-08 09:57:59 | DEBUG | Looking for jobs to run
2019-09-08 09:57:59 | DEBUG | Next wakeup is due at 2019-09-08 09:58:09.453275+02:00 (in 9.998746 seconds)

2019-09-08 09:58:09 | DEBUG | Looking for jobs to run
2019-09-08 09:58:09 | INFO | Running job "test_func (trigger: or[interval[0:00:10], interval[0:00:15], interval[0:00:50]], next run at: 2019-09-08 09:58:09 CEST)" (scheduled at 2019-09-08 09:58:09.453275+02:00)
2019-09-08 09:58:09 | WARNING | Which interval(s) caused this job to execute? I only got args: (), kwargs: {'a': 123, 'b': 345}
2019-09-08 09:58:09 | INFO | Job "test_func (trigger: or[interval[0:00:10], interval[0:00:15], interval[0:00:50]], next run at: 2019-09-08 09:58:09 CEST)" executed successfully
2019-09-08 09:58:09 | DEBUG | Next wakeup is due at 2019-09-08 09:58:19.453275+02:00 (in 9.999404 seconds)

2019-09-08 09:58:19 | DEBUG | Looking for jobs to run
2019-09-08 09:58:19 | INFO | Running job "test_func (trigger: or[interval[0:00:10], interval[0:00:15], interval[0:00:50]], next run at: 2019-09-08 09:58:19 CEST)" (scheduled at 2019-09-08 09:58:19.453275+02:00)
2019-09-08 09:58:19 | WARNING | Which interval(s) caused this job to execute? I only got args: (), kwargs: {'a': 123, 'b': 345}
2019-09-08 09:58:19 | INFO | Job "test_func (trigger: or[interval[0:00:10], interval[0:00:15], interval[0:00:50]], next run at: 2019-09-08 09:58:19 CEST)" executed successfully
2019-09-08 09:58:19 | DEBUG | Next wakeup is due at 2019-09-08 09:58:29.453275+02:00 (in 9.997439 seconds)

2019-09-08 09:58:29 | DEBUG | Looking for jobs to run
2019-09-08 09:58:29 | INFO | Running job "test_func (trigger: or[interval[0:00:10], interval[0:00:15], interval[0:00:50]], next run at: 2019-09-08 09:58:29 CEST)" (scheduled at 2019-09-08 09:58:29.453275+02:00)
2019-09-08 09:58:29 | WARNING | Which interval(s) caused this job to execute? I only got args: (), kwargs: {'a': 123, 'b': 345}
2019-09-08 09:58:29 | INFO | Job "test_func (trigger: or[interval[0:00:10], interval[0:00:15], interval[0:00:50]], next run at: 2019-09-08 09:58:29 CEST)" executed successfully
2019-09-08 09:58:29 | DEBUG | Next wakeup is due at 2019-09-08 09:58:39.453275+02:00 (in 9.997883 seconds)

2019-09-08 09:58:39 | DEBUG | Looking for jobs to run
2019-09-08 09:58:39 | INFO | Running job "test_func (trigger: or[interval[0:00:10], interval[0:00:15], interval[0:00:50]], next run at: 2019-09-08 09:58:39 CEST)" (scheduled at 2019-09-08 09:58:39.453275+02:00)
2019-09-08 09:58:39 | WARNING | Which interval(s) caused this job to execute? I only got args: (), kwargs: {'a': 123, 'b': 345}
2019-09-08 09:58:39 | INFO | Job "test_func (trigger: or[interval[0:00:10], interval[0:00:15], interval[0:00:50]], next run at: 2019-09-08 09:58:39 CEST)" executed successfully
2019-09-08 09:58:39 | DEBUG | Next wakeup is due at 2019-09-08 09:58:49.453275+02:00 (in 9.997841 seconds)

2019-09-08 09:58:49 | DEBUG | Looking for jobs to run
2019-09-08 09:58:49 | INFO | Running job "test_func (trigger: or[interval[0:00:10], interval[0:00:15], interval[0:00:50]], next run at: 2019-09-08 09:58:49 CEST)" (scheduled at 2019-09-08 09:58:49.453275+02:00)
2019-09-08 09:58:49 | WARNING | Which interval(s) caused this job to execute? I only got args: (), kwargs: {'a': 123, 'b': 345}
2019-09-08 09:58:49 | INFO | Job "test_func (trigger: or[interval[0:00:10], interval[0:00:15], interval[0:00:50]], next run at: 2019-09-08 09:58:49 CEST)" executed successfully
2019-09-08 09:58:49 | DEBUG | Next wakeup is due at 2019-09-08 09:58:59.453275+02:00 (in 9.997944 seconds)

2019-09-08 09:58:59 | DEBUG | Looking for jobs to run
2019-09-08 09:58:59 | INFO | Running job "test_func (trigger: or[interval[0:00:10], interval[0:00:15], interval[0:00:50]], next run at: 2019-09-08 09:58:59 CEST)" (scheduled at 2019-09-08 09:58:59.453275+02:00)
2019-09-08 09:58:59 | WARNING | Which interval(s) caused this job to execute? I only got args: (), kwargs: {'a': 123, 'b': 345}
2019-09-08 09:58:59 | INFO | Job "test_func (trigger: or[interval[0:00:10], interval[0:00:15], interval[0:00:50]], next run at: 2019-09-08 09:58:59 CEST)" executed successfully
2019-09-08 09:58:59 | DEBUG | Next wakeup is due at 2019-09-08 09:59:09.453275+02:00 (in 9.997905 seconds)

2019-09-08 09:59:00 | INFO | Got exit signal, exiting.

编辑:请注意,如输出所示,间隔不正确(调度程序每次等待 10 秒,而它应该先等待 10 秒,然后是 5 秒,然后是 5 秒,然后是 10 秒......) - 但我想这是一个单独的问题。

【问题讨论】:

    标签: python apscheduler


    【解决方案1】:

    根据文档,在组合触发器时,

    总是返回所有给定触发器可以同意的最早的下一次触发时间。当任何给定触发器完成其计划时,触发器被认为已完成。

    当使用 OR 时,只有一个为真。

    此外,间隔触发器通过在执行时将间隔添加到当前时间来创建下一个触发时间。

    尽可能严格地解释这一点,这意味着在您的示例中它将始终只使用 10 秒触发器。

    现在关于获取触发器,触发器是作业对象的一个​​属性,所以你不能从函数中访问它。即便如此,使用job = scheduler.get_job(id)trigger = job.trigger 通过其ID 获取作业对象将为您提供您定义的整个组合触发器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多