Как вы отлаживаете модуль mod_perl2 без перезапуска? - PullRequest
3 голосов
/ 12 февраля 2009

Среда: Apache / 2.2.11 (Win32) mod_apreq2-20051231 / 2.6.2-dev mod_perl / 2.0.4-dev Perl / v5.10.0

Ситуация, очень похожая на описанную в в этом сообщении , но за исключением win32.

У меня есть это в httpd.conf:

PerlModule Apache2::Reload
PerlInitHandler Apache2::Reload
PerlSetVar ReloadAll Off
PerlSetVar ReloadModules "MyPackage::*"

... а также только обработка скрипта mod-perl.

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

Я ломаю модуль и перезагружаю скрипт. Ошибка является полезной, сообщая строку, где я сломал модуль.

(Если я перезагружу снова в этот момент, и он только скажет мне «Неопределенная подпрограмма & ModPerl :: ROOT :: ModPerl :: Registry ...», потому что он не смог загрузить файл в первый раз. Но либо как все еще происходит следующее поведение.)

Я возвращаю разрыв и тоже касаюсь файла сценария, чтобы он перезагрузил модуль и перезагрузил. Теперь он говорит:

Attempt to reload MyPackage/Foo.pm aborted.
Compilation failed in require at E:/dev/test.pl line 4.

И даже если я прикоснусь к скрипту и модулю, я не могу заставить его перезагрузиться правильно, кроме как перезапуском веб-сервера.

Разбивка только самого скрипта (в отличие от модуля) работает нормально: правильные ошибки и их повторное возвращение приводят к его повторной работе после перезагрузки.

После каждого из этих действий я перезапускал веб-сервер перед тестированием:

  1. Я пытался сделать след, но линия, что он продолжает выдавать ошибку это строка ModPerl / RegistryCooker.pm 204, который является просто линией, которая eval {} s весь сценарий.

  2. Я пытался изменить "использовать предупреждения FATAL => «все» «просто» использовать предупреждения "в сценарии и модуль. Не имеет значения.

  3. Я пытался отключить мой пользовательский Функция $ SIG {__ DIE__}. не имели Сделать разницу. (Ну только в где появилась ошибка, конечно, но сгенерированные ошибки были такой же.)

  4. По ссылке для обсуждения в начале обнаружил, что MaxRequestsPerChild был 0 за все это время, и я попробовал ThreadsPerChild 1, но без разницы. Я попытался MaxRequestsPerChild к 1, который решает странные поведения этого вопроса, но перезапускает веб-сервер после каждого отдельного запроса:

    Child 7072: Process exiting because it reached MaxRequestsPerChild. Signaling the parent to restart a new child process.
    Parent: Received restart signal -- Restarting the server.
    

    Это не очень хорошее решение, так как у меня есть значительный кусок кода, который запускается при первом обращении к странице.

  5. Также согласно обсуждению, я запускаю httpd как службу, поэтому я добавил -X в окно параметров службы и нажал Start, и он все еще пытался запустить полные три минуты спустя (обычно запускается в течение 3 секунд .) Даже получил сообщение об истечении времени ожидания. Завершение процесса с помощью диспетчера задач и подтверждение того, что я не смог открыть страницу через веб-браузер. Запустил httpd -X из командной строки. По-прежнему такое же поведение, как и в начале этого вопроса. Также мне показалось странным, что -X не было в списке при запуске httpd - ?. Может быть, это не доступно на win32 MPM?

  6. В этой теме Дэвид отмечает:

    Мой опыт устранения неполадок этого вид вопроса показал, что его вероятно, что пакет, который был выгружено удалено значение, сохраненное в пространство пакета модуля перезагружено (вероятно, установлен на время начала блока) что последующее требование не восстановление.

    Но это не относится к моему коду. Введенная мной ошибка 'break the script' просто добавляет дополнительную строку 'my $ var' над уже существующей, чтобы вторая жаловалась, что она уже объявлена.

Нет ли способа работать с модулями mod_perl2 без перезагрузки веб-сервера после каждой перезагрузки (будь то автоматически, через MaxRequestsPerChild или вручную, как раньше)?

1 Ответ

2 голосов
/ 17 февраля 2009

Скопируйте подпрограмму в скрипт, из которого вы ее вызываете, и поместите этот код перед копией:

package MyPackage::Foo;
no warnings 'redefine';

Когда вы закончите вносить изменения, верните сабвуфер обратно в текущий модуль.

...