Ещё пол-года назад я опубликовал свой open source фреймворк regta для создания регулярных задач aka. Cron оптимизированный специально для python с рядом нововведений, но я вообще никак не стал заявлять о его создании. Дело в том, что я считал, что он не достаточно хорош, т к в нём все еще не было важного преимущества, которое я задумывал. Эта особенность оказалась столь нова и необычна, что я даже решил вынести её в отдельный программный пакет. Об этом пакете сейчас и пойдёт речь.
Представьте, что у вас есть контейнер с шедулером и настроенный ci. И, допустим, у вас есть задача, которая выполняется раз в 12 ч. Ну, например, отправка уведомлений. Вот проходит 11 ч и выполнение должно произойти через 1 ч, но вдруг разработчик вносит в код задачи изменения: он делает коммит и контейнер с шедулером редеплоится согласно ci. Теперь счётчик у нашей задачи сбросился и отсчет 12 ч начался сначала. Мы получили серьёзное смещение. Теперь интервал составит 23 ч вместо 12, и ошибка продолжит накапливаться с каждым редеплоем или рестартом сервера. А все может быть ещё серьёзнее. Что если у задачи есть первичный запуск перед стартом счётчика? Ну, как в cron. Тогда мы, наоборот, получим очень короткий интервал, что ещё хуже. Как же решить такую проблему?
Самый очевидный и распространенный способ - это где-то хранить состояния всех задач. Это хороший подход, но его минус в потребности такого хранилища: мы вынуждены поднимать и поддерживать кеш хранилище или бд. Мне же хотелось иметь возможность создать действительно легкую single-container систему без внешних зависимостей.
Предложенная мною идея заключается в вычислении моментов срабатывания, отталкиваясь от общей для всех статической временной отметки: начало эпохи Unix. Unix - одна из первых операционных систем из которой уже произрастают все современные, этакий титан-прародитель. Все ОС унаследовавшие ее принципы называют Unix-подобными, а момент запуска называют началом эпохи Unix. Полночь 1 января 1970 г по UTC - это отметка, которая вшита в каждый компьютер на земле, в каждый чип, способный отсчитывать дату и время. Это единая точка отсчета времени для всех машин, независимо от того, когда они были созданы и в каком часовом поясе находятся. За нее я и предлагаю зацепиться при расчете периодичности.
Фактически, если отбросить всю несильно сложную математику, описанную в доке для поддержки временных окон, часовых зон, точного времени и т д, то подход сводится к поиску остатка от деления времени со старта эпохи Unix на регулярный период. Пропуская текущую отметку времени через такую функцию, мы всегда будем получать смещение до ближайшего времени срабатывания, независимо от текущего момента, что позволяет избавиться от задачи хранения состояний. Такой подход я называю Моменто-независимыми периодами. Модуль regta-period реализует предложенный подход, уже опубликован и будет вшит во фреймворк regta по умолчанию со следующей его версии. Тогда я уже и опубликую его гордый обзор! #tech
Дока: regta-period.Alinsky.tech
Репа: github.com/SKY-ALIN/regta-period
Post #49
785
- 👏 5
- ❤ 2
- 👍 2