СоХабр закрыт.

С 13.05.2019 изменения постов больше не отслеживаются, и новые посты не сохраняются.

| сохранено

H FastCGI Finish Request — фоновое выполнения задач в php в черновиках Recovery Mode Tutorial

Я об этом не нашёл статьи на хабре, по этому решил сделать пост. Ты узнаеш, как можно делать задачи в фоне и не мучить пользователя с ожиданием, например конвертации большого видео.

Как всё у тебя сейчас


1. %username% шлёт тебе запрос на сервер.
2. Скрипт смотрит, что тут идёт конвертация видео, отправка сообщения на email(подставить нужное) и ничего не покажет пока работа не закончиться.

Кэп, я как бы знаю, что у меня на сервере делается


Хорошо, хорошо… Давай посмотрим на твой код(я схематически):

Как мы видим пока всё не будет сделано, %username% не увидит ничего. Как нужно сделать:
Если у вас fastcgi измените свой код так:(если нет, бегите удаляйте апач, и поставьте уже nginx + php-fpm)

Сессии


Казалось бы, всё, но не тут то было… Если ты используеш сессии то нужно их закрывать. Всего-то перед fastcgi_finish_request добавить:
session_write_close();

чтоб, было как-то так:

По правилам, юзабилити, нужно ёще оповестить пользователя, если видео загружено и обработано. Так, например делает ВКонтакте.

Заключения


На этом всё, надеюсь я тебе помог.

комментарии (6)

+2
drakmail ,  
Мне кажется, правильнее использовать для этого очереди сообщений и фоновые воркеры, что-нибудь вроде github.com/seatgeek/djjob.
0
drakmail ,  
Но способ интересный.
0
Webius ,   * (был изменён)
Да, нужно их, просто есть задачи где и такие решения можно успешно использовать такое не прибегая к ним. Кстати, какие вы ёще используете кроме djjob и для каких задач?
0
drakmail ,  

Вообще, я сейчас особо на php ничего не пишу, но для рельс/джанго использую delayed_job/celery, с ними интеграция реализована вообще здорово — разница между синхронным выполнением метода и асинхронным — буквально одна строка. Например, для рельс (пример из. офф. документации):

# обычный синхронный вызов метода
@user.activate!(@device)

# асинхронно, с использованием delayed_job
@user.delay.activate!(@device)
+1
WGH ,  
Хм, но если так делать конвертацию видео, то воркер PHP будет ведь заблокирован на это время и не сможет обрабатывать новые запросы вообще?
То есть, грубо говоря, всего десяток запросов на конвертацию видео просто заблокируют на время сервер.
0
KAndy ,  
Можно сделать тоже сервер независимо