Python scheduler добавление задач
С веб-формы в на сервер будет закидываться задача на разное время выполнения.
Но дело в том,что при запуске первой задачи, вторая не запускается.
Пример кода (словарь d приведен как пример входных данных):
def test_run_func_schedule(data):
print('test_run_func_schedule:',data)
def test_send_func_schedule(data):
d= {'vm1': 2, 'vm2': 4, 'vm3': 8}
for k,v in d.items():
schedule.every(v).seconds.do(lambda: test_run_func_schedule(k)).tag('second-tasks', 'VM_'+k)
while 1:
schedule.run_pending()
time.sleep(1)
На консоль выводит только vm1. Остальные не выводит. Как сделать ,чтою задачи остальные так же выполнялись?
Ответы (2 шт):
Короче, разобрался. Использовал apscheduler
from apscheduler.schedulers.background import BackgroundScheduler
for k,v in d.items():
sched.add_job(test_run_func_schedule, 'interval', [k], seconds=v)
sched.start()
Цикл while не должен быть внутри цикла for. Сначала должен до конца выполниться цикл for, в котором у вас добавляются задачи, а потом уже запуститься бесконечный цикл обработки событий. Сейчас у вас добавляется ровно одна задача, а потом сразу запускается бесконечный цикл, остальные задачи не добавляются (очевидно, потому что бесконечный цикл никогда не заканчивается).
Кроме того, лябмда получает значение k из глобальной переменной k (последнее значение), а не значение, которое было на момент создания лямбды.
Нужно или передавать через значение параметра по-умолчанию:
lambda key=k: test_run_func_schedule(key)
Или использовать functools.partial ("частичное применение функции к параметрам", на самом деле создание новой функции, которая при вызове предзаполняет некоторые параметры переданной функции):
functools.partial(test_run_func_schedule, k)
Так должно работать:
import schedule
import time
from functools import partial
def test_run_func_schedule(data):
print('test_run_func_schedule:',data)
d= {'vm1': 2, 'vm2': 4, 'vm3': 8}
for k,v in d.items():
schedule.every(v).seconds.do(partial(test_run_func_schedule, k)).tag('second-tasks', 'VM_'+k)
while 1:
schedule.run_pending()
time.sleep(1)