Продолжить выполнение долго выполняющегося кода после вывода страницы в CakePHP

У меня есть консоль управления внутренними данными, написанная с помощью CakePHP, которая позволяет пользователю управлять некоторыми иерархическими данными. Каждый раз, когда пользователь вносит изменения в данные, я хочу регенерировать файл данных (в данном случае JSON), который используется во внешнем интерфейсе сайта.

Перестройка может занять некоторое время, и я бы хотел, чтобы внутренний интерфейс был немного более отзывчивым. Моя идея состоит в том, чтобы перестроить JSON после того, как новая страница (страница «ваши изменения были сохранены») отображается пользователю. У меня есть некоторый код в обратном вызове afterFilter() в моем app_controller.php, но страница фактически не отображается в браузере, пока не завершится перестроение JSON.

Я нашел примеры кода для простого ванильного PHP, который делает такие вещи, как отправка HTTP-заголовка Connection: Close и/или использует сброс выходного буфера, чтобы сообщить браузеру, что сервер выполнен, в то время как обработка продолжается, но эти методы не делают (насколько мне известно). могу сказать) работать со структурой CakePHP и собственной буферизацией вывода.

Мне бы хотелось иметь метод, который позволил бы мне полностью отобразить представление для пользователя, а затем, как только пользователь загрузит свою страницу, продолжить выполнение перестроения JSON в фоновом режиме.

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

Заранее спасибо.


person theraccoonbear    schedule 15.02.2012    source источник
comment
Я бы предпочел, чтобы вы полностью делегировали эту задачу фоновому демону / заданию cron / работнику очереди, а не совмещали с потоком пользовательского интерфейса.   -  person deceze♦    schedule 15.02.2012
comment
Если бы это был вариант, я бы обязательно это сделал. К сожалению, это не так.   -  person theraccoonbear    schedule 15.02.2012


Ответы (2)


эти плагины очереди cakephp созданы именно для этой цели: https://github.com/MSeven/cakephp_queue

они отделяют внешний интерфейс от внутренних служб, таких как создание файлов.

person mark    schedule 15.02.2012
comment
Это выглядит многообещающе. Есть ли планы сделать их совместимыми с 2.0? Если ничего не началось, я могу рассмотреть возможность разветвления. ;) - person Chuck Burgess; 16.02.2012
comment
ну, я попробовал и почти закончил :), похоже, у меня работает: github.com/dereuromark/cakephp_queue - person mark; 16.02.2012

Вот предложение. Вот как я запускал длительные процессы из пользовательского интерфейса для очистки файлов. Сначала создайте SHELL для выполнения обработки. http://book.cakephp.org/2.0/en/console-and-shells.html#Shell

Это предоставит код, который запустит фоновый процесс, который вы хотите запустить.

Затем настройте метод на стороне пользовательского интерфейса для вызова оболочки. Возьмите PID и сохраните его в базе данных (чтобы вы могли сказать, когда он закончился).

$PID = shell_exec("/path/to/cake/console/cake SHELLNAME SHELLMETHOD");
$this->Jobs->query("UPDATE `jobs` SET `pid` = $pid WHERE `id` = $job_id");

Затем вы всегда можете проверить, запущен ли процесс, проверив файл /proc/$PID.

person Chuck Burgess    schedule 15.02.2012
comment
Это интересный подход. Я выбрал гораздо более трудоемкий способ написания базового интерфейса RESTful и вызова его через AJAX. Я потратил кучу времени, пытаясь заставить работать асинхронный cURL, прежде чем пошел по этому пути. Я думаю, что ваше предложение - хорошая техника, о которой нужно знать. Спасибо. - person Brian Stinar; 01.03.2016