2009-02-11 11 views
3

окружающей среды: Apache/2.2.11 (Win32) mod_apreq2-20051231/2.6.2-DEV mod_perl/2.0.4-DEV Perl/v5.10.0Как вы отлаживаете модуль mod_perl2 без перезапуска?

Ситуация очень похожа на то, что описано в this discussion list post, за исключением находящихся на win32.

Я имею в httpd.conf:

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

... а также только мод-скрипт на 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 в окне параметров службы и нажал кнопку «Пуск», и он все еще пытался начать полные три минуты спустя (обычно начинается в течение 3 секунд.) Даже получил сообщение с тайм-аутом. Убитый процесс через диспетчер задач и проверенный я не мог ударить страницу из веб-браузера. Запустил httpd -X из командной строки. По-прежнему такое же поведение, как и наверху этого вопроса. Также мне показалось странным, что -X не был указан, когда я запускал httpd - ?. Может быть, он недоступен на win32 MPM?

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

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

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

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

ответ

2

Скопируйте подлодку к сценарию вы звоните его из, и поставить этот код перед копией:

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

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

+0

Вам нужно перезагрузить его после копирования (иногда!), Но это полезно до тех пор, во всяком случае. – Kev