Добавьте ручное “ожидание” в новомодном сценарии

У меня есть новомодный сценарий как ниже:

start on stopped hw_boot
script
/usr/bin/python_program
end script

Это хорошо работает. Но оптимизировать, я хотел бы скрыть задержку импорта библиотеки медленного Python (В настоящее время, требуется 5-10 секунд). Один очевидный путь состоит в том, чтобы запустить импорт библиотеки Python даже во время начальной загрузки hw.

Так, что я хочу сделать, что-то как ниже:

start on some_boot_event (this event is earlier than stopped hw_boot)
script
    //import bunch of python libraries that are needed later
    wait for "stopped hw_boot"
    /usr/bin/python_program
end_script

Как мы можем записать логику для ожидания "остановленного hw_boot" в новомодном сценарии?

2
задан 19 August 2017 в 01:51

1 ответ

Я не буду вдаваться в подробности и намечать все Новомодные сценарии для Вас, так как Вы, кажется, знаете, как уже записать им, но я собираюсь показать Вам ключевые роли.

От Вашего вопроса я буду использовать

  • some_boot_event как "более раннее" событие начальной загрузки это, как предполагается, инициировало инициализацию программы Python и
  • stopped hw_boot как даже это, как предполагается, инициировало осуществление программы Python.

Это - то, как это может работать:

  1. Осуществите рефакторинг свою программу Python для включения вызываемой точки входа, которую можно назвать позже в произвольный момент времени от других модулей. (Идеально Ваш модуль/программа Python уже записан тот путь.), Если программа в настоящее время выполняет какую-либо задачу неинициализации во время загрузки модуля, т.е. в глобальной области видимости, необходимо перенести их в методе.

    Например, если Ваш модуль в настоящее время похож на это,

    #!shebang
    import foo, bar
    # ... various constant, class and method definitions ...
    print("Hello World")
    

    необходимо осуществить рефакторинг его к этому:

    #!shebang
    import foo, bar
    # ... various constant, class and method definitions ...
    
    def main():
        print("Hello World!")
    
    if __name__ == "__main__":
        main()
    
  2. Запишите модуль Python, который импортирует основной модуль Вашей программы Python, ожидает сигнала и затем вызывает основной метод основного модуля:

    #!/usr/bin/env python3
    import signal, MyMainModule
    # Perform other initialisation tasks if necessary
    signal.sigwaitinfo((signal.SIGCONT,))
    MyMainModule.main()
    

    Если Вы не можете использовать Python 3, можно ли обратиться к эквиваленту Python 3 Signal.sigwaitinfo в Python 2.7? для чего-то эквивалентного в Python 2.

  3. Запустите Новомодную “сервисную” задачу с предыдущей программы Python в some_boot_event. Давайте назовем его my_service_task.

  4. Запустите вторую Выскочку “одноразовая” задача в stopped hw_boot это отправляет a CONT предупредите к предыдущей задаче:

    set -e
    kill -s CONT -- "$(initctl status my_service_task | grep -oEe '[0-9]+$')"
    

Если необходимо сообщить об информации о статусе от my_service_task к задаче на шаге 4 можно настроить FIFO прежде, чем отправить сигнал в последнем:

#!/usr/bin/env python3
import errno, signal, MyMainModule
# Perform other initialisation tasks if necessary

signal.sigwaitinfo((signal.SIGCONT,))
try:
    return_value = MyMainModule.main()
except Exception as ex:
    return_value = ex
try:
    with open("/var/run/my_service_task.status") as status_fifo:
        print(return_value, file=status_fifo)
except OSError as ex:
    if ex.errno not in (errno.ENOENT, errno.EPIPE):
        raise ex
if isinstance(return_value, Exception):
    raise return_value

На конце чтения:

set -e
STATUS_FIFO=/var/run/my_service_task.status
mkfifo -m 0600 "$STATUS_FIFO"
trap 'rm -f "$STATUS_FIFO"' 0 INT QUIT TERM

kill -s CONT -- "$(initctl status my_service_task | grep -oEe '[0-9]+$')"

read return_value < "$STATUS_FIFO"
# Do stuff with $return_value
3
ответ дан 2 December 2019 в 02:46

Другие вопросы по тегам:

Похожие вопросы: