2010-01-05 2 views
4

Я использую $r->pool->cleanup_register(\&cleanup); для запуска подпрограммы после того, как страница была обработана и распечатана клиентом. Я надеюсь, что клиент увидит полную страницу, и Apache может продолжать выполнять некоторую обработку в фоновом режиме, которая занимает несколько секунд.Почему браузер зависает, когда я регистрирую обработчик очистки в mod_perl?

Но клиентский браузер зависает до тех пор, пока не будет восстановлена ​​подгрузка. Есть ли способ получить apache для завершения соединения с клиентом до все мои коды вернулись?

Я убежден, что сделал это раньше, но я не могу найти его снова.

ответ

1

Используйте систему очередей заданий и выполняйте длительную операцию полностью асинхронно - просто планируйте операцию во время веб-запроса. Очередь заданий также позволяет справляться с ситуациями пиковой нагрузки лучше, чем делать что-то дорогое в самих процессах веб-сервера.

+0

++ Согласен, если это вообще возможно сделать за пределами веб-сервера. Если возникли проблемы (ожидание блокировок и т. Д.), Это может привести к тому, что экземпляр apache будет недоступен для обслуживания запросов и использует всю память Apache для выполнения (возможно, простого) задания. Я видел, что это вызвало большие проблемы в прошлом ... Если вы не можете настроить задание cron или подобное в своей среде хостинга, посмотрите, можете ли вы fork/exec выполнить отдельный процесс для обработки этой задачи. – FalseVinylShrub

0

Вы хотите: flush the buffer. Он не завершает соединение, но ваш клиент увидит выход до завершения задачи.

sub handler { 
     my $r = shift; 
     $r->content_type('text/html'); 
     $r->rflush; # send the headers out 

     $r->print(long_operation()); 
     return Apache2::Const::OK; 
    } 
+0

Мне кажется, что OP хочет запустить длинную операцию в hookup, которая будет вызываться после возврата обработчика. Поэтому я не думаю, что промывка выходного буфера обязательно поможет в этой ситуации. – friedo

+0

hmmm, не уверен. Я прочитал проблему как «клиент не видит никакого вывода до тех пор, пока эта долговременная задача не завершится». Если это настоящая проблема, то промывка должна принудительно отправить вывод в браузер пользователя. С другой стороны, если вывод уже отображается и просто хочет закрыть соединение, я согласен с вами. Наверное, Брайан даст нам знать. – nont

+0

Спасибо nont, это полезно знать. Но фридо правильно интерпретировал мои записки. Я хочу, чтобы клиент показал, что страница полностью загружена. Иными словами, я не хочу, чтобы этот длительный процесс прерывался, если клиент закрывает свой браузер. – aidan

Смежные вопросы