Разгрузка функции сценария в пост-ответ: методы и лучшие практики? - PullRequest
2 голосов
/ 11 октября 2009

Первый

настройки:

У меня есть скрипт, который выполняет несколько задач после того, как пользователь нажимает кнопку «Загрузить», которая отправляет скрипту необходимые ему данные. Теперь эта часть в настоящее время является обязательной, у нас пока нет возможности отключить загрузку и отрисовку из живого источника.

Этот раздел намеренно скучен, чтобы сделать точку. Пропустите, если вы ненавидите это

В настоящее время данные анализируются из действительно необычного источника с использованием регулярных выражений, а затем разбиваются на массивы. Затем он проверяет БД на наличие данных, уже находящихся в диапазоне дат загруженных данных. Если диапазоны дат данных еще не существуют в БД, он вставляет данные и выводит данные об успехе пользователю (есть также некоторые проверки безопасности, проверка источника данных и базовая проверка загрузки) ... Если данные существуют, Затем сценарий получает данные, уже находящиеся в БД, находит различия между двумя наборами, удаляет старые несоответствующие данные, добавляет новые данные, а затем отправляет электронное письмо каждому человеку, затронутому этими изменениями (одно электронное письмо на человек со всеми соответствующими изменениями в указанном электронном письме, что является совершенно другим шагом). Адреса электронной почты извлекаются посредством поиска по LDAP, поскольку в нашей БД есть рабочий адрес, но у LDAP есть свой личный адрес электронной почты, который гарантирует, что они получат электронное письмо до того, как придут на следующий день, и его поймают без уведомления. Наконец, загрузчик данных сообщает: «Изменения были сделаны, электронные письма были отправлены». это действительно все, что их волнует.

Теперь я могу добавить API Календаря Google, который публикует данные (при планировании данных) в Календаре Google пользователя. Я сделал бы это с помощью их рабочего календаря, но я думал, что намочусь с API Google, прежде чем приступить к настройке системы WebDav для Exchange.

</backstory>

Теперь!

Практический вопрос

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

Каков наилучший способ разгрузить часть работы после того, как пользователь получил подтверждение, что БД была обновлена? Это та часть, которая его больше всего волнует, и самая критическая. Уведомления по электронной почте и обновления Календаря Google доступны только для тех, кто пострадал от загрузки, и, если возникнут проблемы с этими уведомлениями, он узнает об этом (а затем услышит об этом) независимо от того, какой сценарий говорит. его первым.

Так есть ли способ, например, запустить cronjob, который запускается при последнем выполнении скрипта? Может ли PHP создавать cronjobs с exec() способностью? Есть ли какой-то нормализованный способ обработки работы после выполнения, которая требует выполнения?

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

Но меня также беспокоит, что это не сделано, так как пользователю необходимо знать, когда все задачи выполнены и т. Д. Итак, это вызывает:

Лучшие практики / более субъективный вопрос

По сути, существует идея, что индикаторы выполнения, разгрузка в реальном времени и другие способы привязывания пользователя к сценарию, - конечно, в сочетании с оптимизацией кода - лучше, предпочтительнее затем просто скажем: «Мы закончили с вашей стороны, если мы вам понадобимся, мы будем уведомлять пользователей» и т. д. и т. д.

Есть ли какие-то БОЛЬШИЕ вещи, которых следует избегать (кроме того, что они вообще не дают пользователю никакой обратной связи)?

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

Ответы [ 2 ]

2 голосов
/ 11 октября 2009

Для этого хороша работа cron. Если все, что вы хотите сделать, когда пользователь загружает данные, это сказать «Эй, пользователь, спасибо за данные!» тогда это будет хорошо.

Если вы предпочитаете более немедленный подход, вы можете использовать exec() для запуска фонового процесса. В среде Linux это будет выглядеть примерно так:

exec("php /path/to/your/worker/script.php >/dev/null &");

Часть & гласит: «Запусти меня на задний план». Часть >/dev/null перенаправляет вывод в черную дыру. Что касается обработки всех ошибок и уведомления соответствующих сторон - это все зависит от дизайна вашего рабочего сценария.

Для более гибкого кроссплатформенного подхода, ознакомьтесь с PHP Manual post

1 голос
/ 19 октября 2009

Есть несколько способов сделать это. Вы могли бы выполнить exec (), как сказано выше, но вы могли бы потенциально столкнуться с ситуацией DoS, если было слишком много отправленных кликов. Расширение pcntl, возможно, лучше в управлении такими процессами. Проверьте этот пост , чтобы увидеть обсуждение (есть 3 части).

Вы можете использовать Javascript для отправки второго поста ajax, который впоследствии запускает соответствующий рабочий скрипт. Используя ignore_user_abort () и отправляя Content-Length, браузер может отключиться раньше, но ваш процесс apache продолжит работать и обрабатывать ваши данные. У Upside нет потенциала форк-бомбы, у Down - больше апачских процессов.

Еще одним вариантом является использование cron в фоновом режиме, который просматривает таблицу очередей процессов, чтобы сделать что-то «позже» - вы вставляете элементы в эту таблицу на внешнем интерфейсе, удаляете их во внутреннем интерфейсе во время обработки (см. Zend_Queue ).

Еще один способ - использовать более распределенную рабочую среду, такую ​​как gearmand , которая может обрабатывать элементы на других машинах.

Все зависит от ваших общих возможностей и требований.

...