Задачка на вечер:
Дано: задание, которое нужно выполнять в заданные промежутки времени, модуль Python schedule.
Задача: запускать одну и ту же задачу с разными значениями offset раз в 10 сек, так, чтобы 0ffset=119 запускался в 10 сек от начала каждой минуты, offset=219 на 20й секунде каждой минуты и так далее.
Все что пока смог сделать – заставить выполняться задачу каждую 10ю секунду, НО! это грозит тем, что каждые 10 сек в очередь добавляется каждая след. задача, так что может выполняться все куда чаще, чем раз в 10 сек.
Есть идея – сделать задержку в 10 сек после каждого добавления задачи в очередь, тогда может получиться задержка в 20 сек, потом выполнение подряд нескольких задач, и снова 20 сек задержки.
Сломал голову себе, сломаю и вам.
from time import strftime, sleep import schedule def del_comments_offset(offset): print("Func start") try: delete_comments_older(logFile, token, tk_owner_id, tk_group_id, tk_domain, offset) except: log_block("ERROR!!! : Connection error!") offsets = [119,219,319,419,519,619,719,819,919,1019] times = [10,20,30,40,50,60] for offset in offsets: schedule.every(10).seconds.do(del_comments_offset, offset=offset) sleep(1) # schedule.run_pending() while True: schedule.run_pending() sleep(1)
Говнокодь
@
Быстроотвечай
Вариант 1
Делаем счетчик временной паузы в цикле + 5, так после каждого выполнения скрипт будет ждать на 5 сек больше от прошлого выполнения.
Задача будет выполняться таким образом, раз в каждые 5, 15, 25, 35, 45 и т.д. секунд, при этом никогда не будет возникать ситуация, когда в очереди накопится сразу несколько задач с интервалов в 1 сек!
Ееее, велосипед!
def del_comments_offset(offset, sleep_time): start = time() print("Func start") try: delete_comments_older(logFile, token, tk_owner_id, tk_group_id, tk_domain, offset) sleep(sleep_time) end = time() print("Time spent: "+" "*6+str((end - start))) except: log_block("ERROR!!! : Connection error!") offsets = [119,219,319,419,519,619] sleeping = 0 for offset in offsets: schedule.every(10).seconds.do(del_comments_offset, offset=offset, sleep_time=sleeping) sleeping = sleeping + 10 while True: schedule.run_pending() sleep(1)
Лог выполнения:
C:\Python34\python.exe D:/Projects/PycharmProjects/depot/Work/vkontakte_tools/comments_delete/worker_comments_delete.py Func start delete_comments_older started: 23-07-2016 - 19:51:13 Offset: 19 Nothing to delete this time 0 Bot Time spent: 6.58437705039978 Func time spent: 6.741384983062744 Func start delete_comments_older started: 23-07-2016 - 19:51:30 Offset: 119 Nothing to delete this time 0 Bot Time spent: 5.623322010040283 Func time spent: 15.626893997192383 Func start delete_comments_older started: 23-07-2016 - 19:51:55 Offset: 220 Bot Time spent: 7.311417818069458 Func time spent: 27.313562154769897 Func start delete_comments_older started: 23-07-2016 - 19:52:33 Offset: 321 Bot Time spent: 6.506373167037964 Func time spent: 36.51088190078735 Func start delete_comments_older started: 23-07-2016 - 19:53:19 Offset: 422 Bot Time spent: 5.712325811386108 Func time spent: 45.71561312675476 Func start delete_comments_older started: 23-07-2016 - 19:54:15 Offset: 523 Bot Time spent: 6.293359994888306 Func time spent: 56.29761600494385 Func start delete_comments_older started: 23-07-2016 - 19:55:21 Offset: 624 Bot Time spent: 5.933340072631836 Func time spent: 65.93777203559875 Func start delete_comments_older started: 23-07-2016 - 19:56:37 Offset: 725 Bot Time spent: 6.20735502243042 Func time spent: 76.21135902404785 Func start delete_comments_older started: 23-07-2016 - 19:58:03 Offset: 826 Bot Time spent: 6.1743528842926025 Func time spent: 86.17792797088623 Func start delete_comments_older started: 23-07-2016 - 19:59:40 Offset: 927 Bot Time spent: 7.393422842025757 Func time spent: 97.39816999435425 Func start delete_comments_older started: 23-07-2016 - 20:01:27 Offset: 1028 Bot Time spent: 7.303418159484863 Func time spent: 107.30813789367676 Func start delete_comments_older started: 23-07-2016 - 20:01:35 Offset: 19 Nothing to delete this time 0 Bot Time spent: 6.035346031188965 Func time spent: 6.039345979690552 Func start delete_comments_older started: 23-07-2016 - 20:01:51 Offset: 119 Nothing to delete this time 0 Bot Time spent: 5.772330045700073 Func time spent: 15.776902198791504 Func start delete_comments_older started: 23-07-2016 - 20:02:17 Offset: 220 Bot Time spent: 7.519429922103882 Func time spent: 27.522573947906494 Func start Process finished with exit code -1
Вариант 2
Задать кроме того, таким же образом значение every в моменте добавления функции в очередь.
Плохая идея, начинается та самая неразбериха с беспорядочным выполнением функций, когда время одной наслаивается на время другой.
C:\Python34\python.exe D:/Projects/PycharmProjects/depot/Work/vkontakte_tools/comments_delete/worker_comments_delete.py Func start delete_comments_older started: 23-07-2016 - 19:05:54 Arguments are: typical_kirovohrad 119 Time spent: 5.26430082321167 Func start delete_comments_older started: 23-07-2016 - 19:06:04 Arguments are: typical_kirovohrad 219 Time spent: 15.48288607597351 Func start delete_comments_older started: 23-07-2016 - 19:06:21 Arguments are: typical_kirovohrad 119 Time spent: 4.481256008148193 Func start delete_comments_older started: 23-07-2016 - 19:06:25 Arguments are: typical_kirovohrad 319 Time spent: 24.470399856567383 Func start delete_comments_older started: 23-07-2016 - 19:06:51 Arguments are: typical_kirovohrad 419 Time spent: 34.438366174697876 Func start delete_comments_older started: 23-07-2016 - 19:07:25 Arguments are: typical_kirovohrad 519
Вариант 3
Здесь может быть ваш вариант, который должен оказаться лучшим, по сравнению с велосипедами выше.
Вариант 4
Все это фигня дурная, ибо зачем добавлять в цикле задачу, которая сама по себе должна выполняться в цикле в 10 сек?
Вот окончательный вариант без велосипеда:
def del_comments_offset(offset, sleep_time): print("Func start") start = time() try: sleep(sleep_time) delete_comments_older(logFile, token, tk_owner_id, tk_group_id, tk_domain, offset) end = time() print("Func time spent: "+" "*6+str((end - start))) except: log_block("ERROR!!! : Connection error!") offsets = [19,119,220,321,422,523,624,725,826,927,1028] sleeping = 0 for offset in offsets: del_comments_offset(offset=offset, sleep_time=sleeping) sleeping = sleeping + 10
Лог также работает как в варианте 1, но только не нагружает бредом модуль scheduled, который функционально для других целей вообще служит.
Func start delete_comments_older started: 23-07-2016 - 21:19:03 Offset: 19 Nothing to delete this time 0 Bot Time spent: 6.293816089630127 Func time spent: 6.712736129760742 Func start delete_comments_older started: 23-07-2016 - 21:19:19 Offset: 119 Nothing to delete this time 0 Bot Time spent: 6.146492004394531 Func time spent: 16.172499895095825 Func start delete_comments_older started: 23-07-2016 - 21:19:45 Offset: 220 Bot Time spent: 7.482980966567993 Func time spent: 27.525964975357056 Func start delete_comments_older started: 23-07-2016 - 21:20:23 Offset: 321 Bot Time spent: 6.262005805969238 Func time spent: 36.291008949279785 Func start delete_comments_older started: 23-07-2016 - 21:21:09 Offset: 422 Bot Time spent: 5.882701873779297 Func time spent: 45.9157030582428 Func start delete_comments_older started: 23-07-2016 - 21:22:05 Offset: 523 Bot Time spent: 6.098874807357788 Func time spent: 56.140875816345215
Но все равно это все херня, и сейчас я объясню почему:
- во-первых, модуль scheduler выполняет все “джобы” строго по порядку-очереди, таким образом, пока выполняется “долгая” задача, которая занимает, например 5 минут времени, другая задача, которая выполняется каждые 30 сек – будет стоять в очереди, пока 5минтка не закончится, и потом выполнится столько раз, раз в 30 сек, сколько будет свободно до следующей “джобы” на 5 минут, все это создает задержки, которые в конце-концов из-за путаницы могут суммироваться и достигать часов;
- во-вторых, если запустить несколько “джоб” параллельно, благо модуль это позволяет, можно попасть в ловушку Вконтакта, которая запрещает выполнять более 25 запросов (при условии использования vk execute) – за одну секунду, таким образом, две параллельные “джобы” будут конкурировать и блокировать друг-друга с периодичностью раз в 5 мин, что в итоге может просто-напросто вырубить одну из функций так, как будто бы она и не исполнялась, что равносильно первому варианту с очередью, в сухом остатке.
Что имеем на выходе?
Нужен вариант, когда функция, которая выполняется раз в 30 сек, выполнялась как можно чаще, но в промежутках была возможность вставить части более долгой функции, например, короткая функция выполняется на 30-й секунде, завершает работу на 45й а с 45й до следующей 30й будет выполняться часть долгой функции.
Ну или тот вариант, когда функция выполняется постепенно в разные промежутки: часть в 5 мин, часть в 10, 20, 30 и т.п. Так получится совместить выполнение быстрой функции, которая должна работать регулярно, и долгой функции, которая будет запускаться редко, и удалять комментарии “в глубь” то есть со сдвигом до тысячных постов.
И конечный вариант, конечно просто собрать все комменты, а потом запускать проверку на каждый, но это не вариант, снова проблема параллельных запросов и превышения кол-ва в сек.