Я работаю над приложением, которое периодически вызывает фоновые процессы. Один из них вызывался cron, но я ищу что-то более надежное, поэтому конвертирую его для работы под Supervisor. (Вероятно, он будет работать в течение 10 минут, в течение которых он может определить, что нужно сделать, или что он простаивает. После выхода Supervisor автоматически перезапустит чистый экземпляр.)
Поскольку Supervisor лучше обеспечивает параллельную работу только определенного количества экземпляров чего-либо, я могу работать дольше. Однако это означает, что мои процессы с большей вероятностью получат сигналы завершения либо от kill
напрямую, либо потому, что они были остановлены через Supervisor. Поэтому я экспериментирую с тем, как справиться с этим в PHP.
Похоже, что основным решением является использование pcntl_signal()
вот так :
declare(ticks = 1);
pcntl_signal(SIGTERM, 'signalHandler');
pcntl_signal(SIGINT, 'signalHandler');
function signalHandler($signal) {
switch($signal) {
case SIGTERM:
case SIGINT:
echo "Exiting now...\n";
exit();
}
}
Тем не менее, у меня есть несколько моментов в моем коде, которые могут быть связаны с тщательной обработкой завершения работы. Один из подходов состоит в том, чтобы заставить один обработчик вызывать эти разные вещи, но это потребует некоторого рефакторинга, которого я хотел бы избежать. Альтернативой является добавление pcntl_signal()
везде, где мне это нужно, но, к сожалению, за один раз можно установить только один обработчик.
Однако похоже, что я могу использовать register_shutdown_function()
. Это не перехватывает ^C
или другие знаки завершения сами по себе, и руководство по этому поводу совершенно ясно:
Функции завершения работы не будут выполняться, если процесс будет уничтожен сигналом SIGTERM или SIGKILL.
Что удивительно, так это то, что я обнаружил, что если я использую pcntl_signal()
просто для выхода, то обработчики выключения действительно вызываются. Кроме того, поскольку может быть много обработчиков выключения, это прекрасно решает мою проблему - каждый класс в моем коде, который хочет изящно обрабатывать завершение, может захватывать и управлять своим собственным завершением работы.
Мой первоначальный вопрос: почему это работает? Я попытался зарегистрировать функцию выключения без обработчика сигнала, и это, похоже, не вызывается, как говорится в руководстве. Я предполагаю, что процесс поддерживается PHP для обработки сигнала, который вызывает вызов обработчиков выключения?
Кроме того, могу ли я полагаться на это поведение, когда руководство ставит под сомнение это? Я использую PHP 5.5 и пока не собираюсь обновляться до PHP7. Так что мне было бы интересно, работает ли это на 5.5 и 5.6, на различных дистрибутивах.
Конечно, будет ли это (или не будет) работать на 7.0 и/или 7.1, тоже было бы интересно - хотя я знаю, что галочки будут обрабатываться по-другому в версии 7.1, так что больше шансов, что это будет иметь другое поведение.
:-)
. - person halfer   schedule 17.08.2016