Назад | Перейти на главную страницу

таймер systemd для процесса, который запускается каждые 5 минут, но может работать дольше 5 минут

Я немного поискал и не нашел похожих вопросов.

У меня есть работа, которая должна выполняться каждые пять минут.

Одновременно должно выполняться только одно задание.

Если программа запускается более 5 минут, она должна запуститься немедленно, а не ждать.

В большинстве случаев работа выполняется менее чем за минуту, иногда она должна выполнять действия, которые могут занять до 20 минут.

В настоящее время я запускаю это задание как службу systemd, и задание представляет собой сценарий оболочки, который вызывает фактическую программу в цикле и засыпает между итерациями (5 минут - время последнего выполнения). Отлично работает.

#!/bin/sh
#
# Sample executable repeat-loop
#
# Run my job in a loop.  If it takes less than max_delay seconds
# to run, sleep until it's time to repeat.  If, for some reason, it took longer, just start
# over again immediately.

max_delay=300                       # maximum delay between runs

# Don't allow multiple copies of this script to run
[ "${FLOCKER}" != "$0" ] && exec env FLOCKER="$0" flock -en "$0" "$0" "$@"

restart=0
now=0

while true ; do
    now=`date -u '+%s'`
    if [ $restart -gt $now ] ; then
        sleep `expr $restart - $now`
    fi
    restart=`expr $now + ${max_delay}`

    echo "my job runs here and may take between 30 seconds and 20 minutes to execute"
done

Так как я чертов идиот, я подумал, что было бы здорово изменить это на сервис с одним выстрелом и сработать таймеры systemd.

Я не смог понять, как имитировать такое поведение, используя OnUnitActiveSec или OnUnitInactiveSec...

OnUnitActiveSec будет запускать мой сервис onehot каждые x секунд. OnUnitInactiveSec собирается запустить мой onehot через x секунд после того, как последний раз был прерван.

Есть мысли, кроме "Эй, ваш сценарий оболочки отлично работает, зачем бить себя мертвой лошадью?"

Я должен был лучше протестировать, чем полагаться на мою (неправильную) интерпретацию документов.

Создание файла таймера и использование OnUnitActiveSec указывая на служебный файл, который Type=simple делает именно то, что я хочу. Таймер будет запускаться каждые 5 минут, если процесс длится более 5 минут, он будет вызываться (почти) немедленно. Он не будет вызываться дважды.

Важно использовать simple вместо того oneshot (согласно документации).