Я пишу веб-приложение на PHP с помощью Symfony2. Пользователь может загрузить файл CSV с данными, которые сохраняются в базе данных. Анализ каждой строки файла CSV длится около 0,2 секунд, потому что я делаю некоторые запросы к API Карт Google.
Поэтому, когда вы загружаете CSV-файл с 5000 строк, что является реальным случаем в моем приложении, для анализа всего файла может потребоваться 16 минут.
Я не хочу, чтобы пользователь должен был ждать 16 минут, пока он не сможет продолжить использовать мое приложение. Поэтому мой вопрос: как я могу разобрать CSV-файл в фоновом режиме, чтобы пользователь мог продолжить просмотр?
Попросите загрузить вставить задание в таблицу очередей заданий и регулярно выполняйте команду cron, которая обрабатывает любую работу в таблице очередей заданий.
По мере того, как обработка продолжается при задании, вы можете обновить таблицу заданий, чтобы пользователь мог проверить и увидеть прогресс (например, вы могли бы иметь индикатор выполнения ajax) и узнать, когда задание будет завершено.
Таким образом, вы также отключите загрузку от обработки, и вы можете контролировать, сколько заданий обрабатывается сразу. Наличие длительных запусков рабочих мест непосредственно с пользовательского ввода без системы дросселирования / очередей на месте – отличный способ открыть себя для атаки на отказ в обслуживании …
Вы можете создать kernel.terminate
событий kernel.terminate
и провести там синтаксический анализ. Это событие срабатывает после отправки ответа в браузер. Пример внедрения будет,
Объявление сервиса,
//services.yml csv_parse_listener: class: FQCN\Of\CsvParseListener tags: - { name: kernel.event_listener, event: kernel.terminate, method: onKernelTerminate }
Класс слушателя,
namespace Your\namespace; use Symfony\Component\HttpKernel\Event\PostResponseEvent; class CsvParseListener { public function onKernelTerminate(PostResponseEvent $event) { $request = $event->getRequest(); if($request->get('_route') !== "Your_route"){ return; } $csvFile = $request->files->get('file_field_name'); //move file using $csvFile->move() //read and parse } }
Вы можете написать сценарий, который предназначен только для обработки CSV-файла, и exec (), этот скрипт из сценария, который управляет загрузкой. В системах * IX вы можете сделать команду, запущенную exec (), запущенной в фоновом режиме, добавив символ &.
Вероятно, вы также захотите включить скрипт, который позволит пользователю проверить ход обработки.