launchd startInterval коротше, ніж час, необхідний для завершення сценарію


2

Я використовую launchctl для завантаження / запуску мого Python скрипт, і він працює в певній мірі. Це запускає колись 120s, але деякий час мій сценарій бере 500s щоб побігти та моя теорія що це я маю процес бігаючий це restarts це а не дозволяючий перший бігають.

Я думаю, що відбувається: - запустіть tester.py (оціночний час tester.py для завершення 400-х) - після 120-х - запустити tester.py знову і відмовитися від першого

Що я хочу: Для завершення першого tester.py не перезавантажте його.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>BuildNotification.py</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/bin/python</string>
        <string>/Users/xcuer/tester.py</string>
    </array>
    <key>StartInterval</key>
    <integer>120</integer>
    <key>TimeOut</key>
    <integer>7200</integer>
    <key>ExitTimeOut</key>
    <integer>7200</integer>
</dict>
</plist>

Я намагаюся придумати гарне рішення, крім перевірки сценарію на попередні виклики та виходу ...
bmike

@bmike Я намагаюся, якщо crontab вирішує цю проблему
donttellunclesam

1
Файл блокування буде традиційним рішенням для цієї ситуації. Чи можна змінювати сценарій?
Graham Miln

@GrahamMiln Як б файл блокування працював для мого рішення? Чи є спосіб, я можу написати сценарій bash, який запускає callct замість самого скрипта python? Чи має laucnhctl спосіб перевірити, якщо служба в даний час працює?
donttellunclesam

1
Я використав відповідь @GrahamMiln crontab і launchd робочих місць. Його тест на 4 оболонки може бути дуже легко написаний на Python, Perl, AppleScript або будь-якій мові сценаріїв.
daniel Azuelos

Відповіді:


1

launchd фокусується на запуску робочих місць і збереження запущених робочих місць, він не має механізму для роботи з перекриттям.

Заблокувати файл

Традиційно в середовищі UNIX файл блокування використовується для припинення багаторазового запуску процесів.

Основні кроки:

  1. На запуску сценарію, якщо файл блокування вже існує, зупиніть скрипт.
  2. На запуску скрипта, якщо файл блокування не існує, створіть файл блокування.
  3. На завершення сценарію видаліть файл блокування.

На MacOS створіть файл блокування /var/tmp для комп'ютерних процесів.

Зразок реалізації

if ! mkdir /var/tmp/myscript.lock 2>/dev/null; then
    echo "Myscript is already running." >&2
    exit 1
fi

Подивитися Швидкий і брудний спосіб, щоб забезпечити одночасне виконання лише одного екземпляра сценарію оболонки і Який найкращий спосіб забезпечити виконання лише одного екземпляра сценарію Bash? для зразків сценаріїв.

Потенційні проблеми

Є крайні випадки.

launchd бажає, щоб робота виконувалася на найменше n секунд перед закінченням . Коли скрипт знаходить існуючий файл блокування, розгляньте сплячий режим n секунд, а потім виходу.

Що станеться, якщо ваш скрипт буде убитий або вийшов через помилку? Чи можете ви переконатися, що файл блокування буде видалено?

У C, трюк для забезпечення видалення файлу - створення, відкриття та видалення файлу - видалений файл, відкритий на UNIX, залишатиметься, поки процес відкриття не завершиться. Файл видаляється, навіть якщо процес завершиться аварією.

У скрипті оболонки вловлюйте сигнал завершення і переконайтеся, що файл видалено.

Іншою потенційною проблемою є перевірка існуючого файлу. Ця перевірка може статися з фракцій секунди перед завершенням попереднього сценарію. Це буде рідко, але можливо. Наведений вище підхід вимагає подолання цього.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.