AJAX: как получить обратную связь с результатами работы в веб-приложениях и избежать тайм-аутов при длительных запросах?

Это общий дизайн вопроса о том, как сделать веб-приложение, которое будет получать большое количество загруженных данных, обрабатывать их и возвращать результат, все без страшного вращающегося пляжного шара в течение 5 минут или возможного таймаута HTTP.

Здесь требования:

  • создать веб-форму, где вы можете загрузить CSV файл, содержащий список URL-адресов
  • когда пользователь нажимает кнопку "отправить", сервер извлекает файл и проверяет каждый URL-адрес, чтобы узнать, жив ли он и какой тег заголовка страницы.
  • результатом является загружаемый CSV файл, содержащий URL-адрес, а результат HTTP-код
  • входной CSV может быть очень большим ( > 100000 строк), поэтому процесс выборки может занять 5-30 минут.

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

Я использую perl, набор шаблонов и jquery, но любое решение, использующее любую веб-технологию, будет приемлемым.

изменить Пример возможного решения в этом вопросе: Как реализовать базовый "длинный опрос" ?

Ответ 1

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

В любом случае моя рекомендация - передать работу другому процессу, когда он доберется до сервера.

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

Пакетный процессор может быть реализован несколькими способами:

  • Вилка и отсоедините ребенка от ввода-вывода для завершения пакетной обработки. Родитель завершает веб-запрос.
  • Сохранить загружаемый контент в очередь обработки (например, файл в файловой системе, записи в базе данных) и сообщить веб-серверу о внешнем процессоре - либо пользовательском демонах, либо нестандартном планировщике, например "at", для систем * nix.

Затем вы можете предложить пользователю несколько способов отслеживания процесса:

  • Страница подтверждения загрузки содержит синхронный живой монитор пакетного процесса (через COMET или Flash). По завершении страницы подтверждения может направить пользователя на загрузку.
  • Как и выше, но монитор не работает, но вместо этого использует периодический опрос через AJAX или обновление метаданных страницы
  • Страница мониторинга очередей, которая показывает статус любого пакетного процесса, который у них запущен.

Пакетный процессор может передавать статус через несколько методов:

  • Обновить запись в базе данных
  • Создание журнала обработки
  • Использовать именованный канал

Существует ряд преимуществ для передачи кода другому процессу:

  • Процесс продолжится, КОГДА пользователь случайно остановит браузер.
  • Использование внешнего процесса заставляет вас сообщать статус партии таким образом, чтобы вы могли отсоединить монитор и снова подключиться в любое время. Например: КОГДА пользователь случайно перемещается в сторону от страницы до завершения процесса.
  • Легче выполнять пакетное дросселирование и отсрочку, если вы решите, что вам нужно разложить свою пакетную обработку на низкоскоростные трафик.
  • Вам не нужно беспокоиться о тайм-аутах в Интернете (на стороне клиента или на стороне сервера).
  • Вы можете перезапустить веб-сервер, не беспокоясь о том, прерываете ли вы пакетный процесс.

Ответ 2

Простейшим может быть пакетный процесс или даже поток задания. Если вы относитесь к нему как к таблице данных, которая у вас есть на вашей странице. Если в таблице есть > 100000 записей, вы просто запросите все записи сразу. Я бы сделал это:

  • Отправить запрос на скачивание файла.

  • Отправьте запрос на обработку 100 (произвольных номеров) записей.

    а. Записи процесса.

    б. Сохраните временный файл csv.

    с. Ответ обратно со статусом полного/ не завершен.

    д. Если статус не завершен, повторите второй шаг.

Ответ 3

Вы упомянули, что клиенту нельзя доверять, поэтому я рекомендую (на стороне клиента) предварительный анализ файла за X количество записей, добавляя контрольную сумму к каждому подмножеству записей, а затем позволяя клиенту фиксированное количество подключений для загрузки через прокси-сервер, чтобы вы могли более точно отслеживать прогресс.