@stasboiko

Как остановить экспортирование файла, если процесс экспорта уже запущен?

Речь идет о php.
По нажатию на кнопку СТАРТ запускаем экспорт.
Это просто цикл который построчно записывает данные в csv файл.
Время полного экспорта занимает примерно 100 секунд.
Есть кнопка ОТМЕНА.
Если нажать на эту кнопку то экспорт должен остановиться.
То есть если пользователь нажал на СТАРТ то началась запись в файл и если через 50 секунд нажать на ОТМЕНА то цикл должен остановиться.

Что я попробовал сделать:
на каждой итерации цикла я добавил проверку (флаг) нужно ли остановить цикл.
по нажатию на кнопку ОТМЕНА выполняется ajax запрос, который записывает переменную в реддис (на каждой итерации цикла эта переменная проверяется).
Проблема в том, что если мы нажмем на кнопку СТАРТ а затем на кнопку ОТМЕНА то ajax запрос отработает только после полного выполнения цикла.
То есть ajax запрос который меняет флаг отработает только после полного прохода цикла.
То есть значение флага будет присвоено только после прохода цикла.
Я не понимаю почему.
ajax должен работать асинхронно, ведь верно?
  • Вопрос задан
  • 81 просмотр
Решения вопроса 1
@ffosters
Можно получить идентификатор процесса во время запуска скрипта и остановить процесс при необходимости, примерно так:

$pid = getmypid();

// Add process ID to storage
// ...

//

// Retrieve process ID from storage
// ...

shell_exec(strtr('kill :pid', [
    ':pid' => $pid,
]));
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
xmoonlight
@xmoonlight
https://sitecoder.blogspot.com
Ищите ошибку в изменении (ОТМЕНА) и при получении/проверке переменной (внутри цикла).
В целом - всё должно работать...
Ответ написан
@rPman
Что у вас за вебсевер? В настройках сервера можно определить, сколько одновременно запросов он может обрабатывать, а некоторые (например встроенный в php по ключу -S ) и вовсе умеют только один поток, остальные запросы в этот момент ждут.

Правильное и универсальное решение - вынести длительные задачи в сторонний сервис/процесс, запускаемый независимо (например php-cli запускаемый с помощью services а во время отладки просто в консоли или screen). Совсем правильно - организуйте ваш сервис в виде приложения с использованием например reactphp (websocket сервер например и проксируйте его через ваш веб сервер), при этом организуйте работу полностью асинхронно (есть методы для асинхронной работы со всем включая работу с файлом, т.е. ваш цыкл будет выглядеть как метод, который указан в качестве вызова успешной записи в файл для записи следующей порции данных)

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

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы