Как получить доступ к возвращаемому значению из apscheduler? - PullRequest
1 голос
/ 02 апреля 2019

Я не могу понять, как получить доступ к возвращаемым значениям из запланированных заданий в apscheduler.Задание должно выполняться в разное время каждый день, и мне нужно возвращаемое значение из сегодняшнего задания, чтобы запланировать завтрашнее задание.

Эта ссылка ( как получить возвращаемое значение из заданий apscheduler )представляется лучшим предыдущим ответом на этот вопрос.Он предлагает добавить слушателя в планировщик.Я добавил слушателя, но я не уверен, как получить доступ к его возвращаемому значению.Я могу получить доступ к слушателям, подключенным к планировщику, но не могу получить доступ к их выходам.Слушатель, job_runs () в приведенном ниже коде, будет печатать при выполнении запланированного задания.

Кроме того, я знаю, что мне нужен доступ к JobExecutionEvent (https://apscheduler.readthedocs.io/en/latest/modules/events.html#module-apscheduler.events), который содержит возвращаемое значение из функции.

Во-первых, я хочу получить доступ к функции run_all (), где выполняется несколько операций, но я просто возвращаю True для контрольного примера.

from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.events import EVENT_JOB_EXECUTED, EVENT_JOB_ERROR, JobExecutionEvent
from datetime import datetime, timedelta
import logging


def run_all():
    return True


def job_runs(event):  # listener function
    if event.exception:
        print('The job did not run')
    else:
        print('The job completed @ {}'.format(datetime.now()))


def job_return_val(event):  # listener function
    return event.retval

Затем я настраиваюпланировщик, добавьте прослушиватели и добавьте задание. Триггер настроен на запуск функции через 1 минуту после добавления задания в планировщик.

  scheduler = BackgroundScheduler()
  scheduler.add_listener(job_runs, EVENT_JOB_EXECUTED | EVENT_JOB_ERROR)
  scheduler.add_listener(job_return_val, EVENT_JOB_EXECUTED)
  cron_args = datetime_to_dict(datetime.now() + timedelta(minutes=1))
  job = scheduler.add_job(run_all, "cron", **cron_args)

Далее я запускаю планировщик и распечатываю запланированное заданиеКроме того, я настроил ведение журнала, чтобы знать, где находится планировщик.

  test = scheduler.start()
  scheduler.print_jobs()
  logging.basicConfig()
  logging.getLogger('apscheduler').setLevel(logging.DEBUG)

При включенном ведении журнала планировщик сообщает, что задание запущено и удалено из планировщика, как я и ожидаю. Job_runs () выводит правильный вывод в консоль. А с точками останова я знаю, что вызывается job_return_val (). Однако я не знаю, куда отправляется возвращаемое значение.вызываться в другом потоке под названием APScheduler.Я не знаю много о темах, но это имеет смысл.Однако я не понимаю, когда выходные данные этого потока возвращаются в основной поток.

Наконец, я попытался создать экземпляр JobExceptionEvent с помощью кода, job_id, jobstore и schedule_run_time, доступного из атрибутов планировщикаи job, но JobExceptionEvent, похоже, не знает, что событие было запущено в планировщике.Это также, кажется, имеет смысл из-за многопоточности, описанной в предыдущем абзаце.

Любая помощь в сортировке этого будет отличной!

Ответы [ 2 ]

0 голосов
/ 03 апреля 2019

То, что вам нужно, потребует реализации функции с сохранением состояния .

0 голосов
/ 03 апреля 2019

Возвращаемое значение слушателя нигде не используется (см. код ), поэтому нет никакого смысла возвращать любое значение в любом случае.Если вам нужно запланировать другое задание на основе значения предыдущего задания (полученного в слушателе через объект события), вы должны сделать это прямо в этом слушателе.

РЕДАКТИРОВАТЬ: Комупроиллюстрируйте, как это сделать (и докажите, что это возможно), посмотрите этот пример кода:

from datetime import datetime
import time

from apscheduler.events import EVENT_JOB_ERROR, EVENT_JOB_EXECUTED
from apscheduler.schedulers.background import BackgroundScheduler


def tick():
    print('Tick! The time is: %s' % datetime.now())


def tack():
    print('Tack! The time is: %s' % datetime.now())


def listener(event):
    if not event.exception:
        job = scheduler.get_job(event.job_id)
        if job.name == 'tick':
            scheduler.add_job(tack)


if __name__ == '__main__':
    scheduler = BackgroundScheduler()
    scheduler.add_listener(listener, EVENT_JOB_EXECUTED | EVENT_JOB_ERROR)
    scheduler.add_job(tick, 'interval', seconds=5)
    scheduler.start()

    try:
        while True:
            time.sleep(1)
    except (KeyboardInterrupt, SystemExit):
        scheduler.shutdown()

Вывод:

(venv) pasmen@nyx:~/tmp/x$ python test.py 
Tick! The time is: 2019-04-03 19:51:29.192420
Tack! The time is: 2019-04-03 19:51:29.195878
Tick! The time is: 2019-04-03 19:51:34.193145
Tack! The time is: 2019-04-03 19:51:34.194898
Tick! The time is: 2019-04-03 19:51:39.193207
Tack! The time is: 2019-04-03 19:51:39.194868
Tick! The time is: 2019-04-03 19:51:44.193223
Tack! The time is: 2019-04-03 19:51:44.195066
...
...