Прогресс-бар для фоновых задач на Laravel и React

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

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Прогресс-бар для фоновых задач на Laravel и React
Средний
~2-3 дня
Часто задаваемые вопросы

Почему прогресс-бар для фоновых задач расходится с реальностью

Задача уходит в очередь задач, воркер её забирает, а пользователь смотрит на полоску. Беда в том, что процент выполнения считается не по самой работе, а рядом с ней: обработчик пишет «начал» и «закончил», и между этими двумя записями полоса стоит на нуле все двадцать минут. Если прогресс всё-таки двигается, он врёт иначе — считает записи, а не их вес: тысяча мелких строк пролетает за секунду, а одна тяжёлая операция держит полосу на 97% столько же, сколько весь остальной пакет.

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

Цена такого сбоя — не кривая полоска, а недоверие ко любому долгому действию: люди начинают дёргать кнопку, поддержка разбирает дубли, администратор не понимает, что реально происходит в очереди. Ниже разбираем, как это закрывается — от того, где хранится прогресс и кто его пишет, до того, как отличить упавший воркер от работающего.

Что даёт достоверный индикатор состояния длительных задач

Достоверность статуса — это контракт между обработчиком очереди Laravel и интерфейсом, а не элемент оформления. Когда прогресс-бар показывает реальную долю выполненного, а не бесконечное «загрузка», пользователь перестаёт перезапускать операцию: повторные запуски падают в разы, потому что никто не дёргает кнопку повторно на тридцатой секунде ожидания.

Второй эффект — снятый класс отказов «задача без статуса». Если обработчик упал, запись висит в состоянии «в работе» неограниченно долго, и поддержка вручную выясняет, что произошло. Периодическая сверка журнала задачи с очередью и перевод зависших процессов в явный статус с причиной закрывают этот сценарий: задача либо завершается, либо честно сообщает об ошибке и остаётся доступной для повтора.

Нагрузка на поддержку падает вместе с неопределённостью. Обращения в духе «оно ещё считается?» уходят, когда на экране видны этап и предсказуемое оставшееся время, а специалисты занимаются настоящими сбоями вместо уточнения состояния.

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

Режимы отображения прогресс-бара: сравнение подходов

Очередь задач на Laravel и интерфейс на React — разные процессы: одна сторона считает шаги, вторая о них не знает. Режим передачи состояния выбирают по двум вопросам: можно ли посчитать объём работы заранее и как быстро клиенту нужно обновление. От этого зависит, показываем ли мы честные проценты или неопределённый индикатор.

Детерминированный счётчик работает, когда задача разбита на порции и после каждой порции обновляется запись «обработано N из M». Тогда шкала отражает реальный ход выполнения, а не активность сервера. Если разбить работу нельзя — например, внутри один длинный вызов — корректнее неопределённый индикатор: он не обещает «осталось две минуты», которые нечем подтвердить.

Вариант Когда подходит Ограничения
Периодический опрос Задача идёт минутами, задержка в несколько секунд допустима Точность ограничена интервалом опроса; каждый клиент добавляет запросы к хранилищу состояния
Поток событий Нужен реальный ход выполнения: проценты, шаги, лог Держит долгие соединения; при обрыве нужен перезапрос состояния
Двусторонний канал Кроме прогресса нужны команды: пауза, отмена, повтор Дороже в поддержке; избыточен, если данные идут только на клиент

На практике берут комбинацию: периодический опрос для списка задач, поток событий для карточки открытой задачи. При обрыве соединения интерфейс возвращается к опросу и перезапрашивает состояние — шкала не залипает на последнем значении. Смена режима не требует переделки самой задачи: счётчик пишется в хранилище состояния, а способ доставки в интерфейс меняется отдельно.

Этапы внедрения: от аудита очереди до передачи регламента

Прогресс — это не анимация на экране, а отражение реального состояния задачи в хранилище. Поэтому порядок работ начинается с разбора того, что происходит на сервере, и заканчивается регламентом, по которому команда дальше работает сама.

  1. Аудит очереди. Разбираем жизненный цикл фоновой задачи: какие обработчики существуют, сколько шагов внутри каждого, где задача может быть перезапущена, отменена или отброшена по таймауту. Результат — карта переходов, на которой строится всё остальное.
  2. Схема статусов. Проектируем конечный набор состояний (в очереди, выполняется, шаг N из M, готово, ошибка) и правила перехода между ними. Отдельно фиксируем поведение при повторном запуске — иначе пользователь увидит два прогресса на одну задачу.
  3. Граница шага. Договариваемся, что считать шагом: единицу работы, которую видно человеку. Слишком крупный шаг даёт «замершую» полосу, слишком мелкий — лишние записи в хранилище и рост нагрузки на него.
  4. Хранилище состояния. Выбираем, где живёт прогресс: кэш, таблица в базе или очередь сообщений. Задаём частоту записи и время жизни записи, чтобы данные не накапливались после завершения задачи.
  5. Передача в интерфейс. Определяем канал обновления — периодический опрос или потоковое соединение, — а также восстановление состояния при перезагрузке страницы и поведение при потере связи. Клиент не должен видеть нулевой прогресс на уже выполненной задаче.
  6. Проверка на нагрузке. Запускаем несколько задач одновременно и смотрим, не растёт ли время отклика, не теряются ли обновления и совпадает ли финальный статус с фактическим результатом обработки.
  7. Передача регламента. Отдаём схему статусов, конфигурацию хранилища, правила добавления новых шагов и разбор типовых сбоев — с этого момента команда расширяет прогресс без нашего участия.

Проверка на нагрузке и передача регламента — не формальность, а точки, где чаще всего всплывают расхождения. Мы закрываем их до сдачи, поэтому после запуска прогресс не расходится с реальностью при первом же сбое обработчика.

Конфигурации, схемы и регламенты, которые остаются у команды

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

  • Конфигурация очередей — какие очереди заведены, какие типы задач в какую попадают, сколько обработчиков на каждую и как настраиваются приоритеты и повторные попытки.
  • Схема жизненного цикла — все статусы задачи от постановки до результата или ошибки, с указанием, какие переходы допустимы и какой статус видит пользователь в прогресс-баре.
  • Политики доступа к статусам — кто из ролей может запускать, останавливать и повторять задачу, кто видит только свой прогресс, а кто — сводку по всем.
  • Инструкция поддержки — типовые ситуации: задача стоит без движения, оборвалась на середине, отработала дважды; что проверить в первую очередь и какие логи смотреть.
  • Порядок отката — как вернуть предыдущее поведение обработки, если нововведение мешает, и какие данные при этом не теряются.
  • Регламент повторного запуска — условия, при которых задачу можно перезапустить безопасно, чтобы не получить дубли результатов.
  • Наблюдаемость — какие метрики по длине очереди и времени обработки снимаются, на каких порогах срабатывают оповещения.

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

Кейс: расхождение индикатора и очереди убрали за две недели

До: индикатор замирал, а задачи терялись молча

Массовая выгрузка отчётов на несколько тысяч строк шла через очередь, но индикатор на экране считал прогресс по счётчику, который обновлялся только после успешного завершения каждой пачки. Если обработчик падал на середине — например, на неожиданном формате даты в одном из файлов, — внешне ничего не менялось: полоса замирала на 60–70%, человек ждал, а задача уже была мертва. Мы разобрали инциденты за месяц: часть выгрузок не доходила до конца, и ни один такой сбой не давал явной ошибки в интерфейсе.

После: состояние сверяется с фактом, а не с ожиданием

Источником правды сделали серверную сторону на Laravel: каждая задача получила журнал шагов, полоса прогресса рисует реально завершённое, считывая состояние из хранилища, а не из памяти обработчика. Падение стало событием — неудачная попытка фиксируется, задача переводится в статус сбоя, остаток пересчитывается заново, а пользователь видит причину и кнопку повтора. Сверку состояния вынесли в фоновую проверку: она периодически сопоставляет очередь, журнал и то, что показано в браузере, и подтягивает расхождения.

Метрики внедрения за две недели: расхождений индикатора с фактом — ноль, молчаливых падений обработчиков — ноль, выгрузок, брошенных на середине, — ноль. Время от сбоя до понятного статуса сократилось с часов ожидания до минут.

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

Что делать, если индикатор внедрён и показывает неверные значения

Расхождение индикатора почти всегда относится к одному из двух классов причин: неверная оценка объёма работы или потеря передачи состояния между обработчиком задачи и интерфейсом. Различить их можно по журналу выполнения: если счётчик растёт ровно, но упирается в верхнюю границу раньше времени — врёт оценка; если значения скачут, откатываются назад или замирают — рвётся передача состояния.

Симптом Вероятная причина Минимальное изменение
Полоса доходит до конца раньше, чем задача завершилась Объём оценён по числу записей, а не по фактической работе Считать общий объём на старте и уточнять его по ходу
Значение откатывается назад Несколько исполнителей пишут в один счётчик Агрегировать прогресс на уровне задачи, а не исполнителя
Полоса замирает на середине Часть этапов не публикует события вовсе Закрыть пропущенные этапы публикацией
После перезапуска счёт идёт с нуля Состояние живёт только в памяти процесса Хранить снимок прогресса в общем хранилище

Дальше решается вопрос объёма правок. Переписывать очередь целиком не нужно: достаточно единого контракта события прогресса — одна точка публикации и явное правило пересчёта процента. Совместимость с текущей очередью при этом сохраняется, потому что меняется слой отчётности, а не постановка и порядок задач.

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

Технические сомнения: надёжность, сопровождение и повторные запуски

Часть вопросов возникает до старта: они про поведение системы в нештатных условиях, а не про внешний вид полосы. Ниже — ответы на те, что задают чаще всего.

Как считать прогресс, если общий объём заранее неизвестен?

Полоса опирается на обработанные записи и подтверждённые пакеты. Если объём уточняется по ходу, показываем текущий этап и оценку оставшегося времени: честно уточняющаяся оценка полезнее застывшей цифры.

Что происходит при сбое обработчика?

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

Задачу смотрят несколько пользователей одновременно — это мешает?

Каждый клиент подписан на канал задания и получает только изменения статуса. Число наблюдателей не влияет на скорость обработки: смотреть вдесятером — то же, что смотреть одному.

Выдержит ли решение пиковую нагрузку?

Подписка на прогресс дешевле самой обработки: клиенты получают только изменения состояния. Задания встают в очередь, обработчик берёт следующее после освобождения — всплеск не превращается в отказ.

Что остаётся на сопровождении после сдачи?

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

Обсудим задачу и вернёмся с оценкой и планом работ

Чтобы вернуться с оценкой, а не с предположениями, нам нужны исходные данные о том, как устроена текущая очередь задач и интерфейс. Прогресс-бар — это по сути контракт между сервером и клиентом: состояние задачи должно переживать перезагрузку страницы, перезапуск обработчика и повторный запуск после сбоя. Поэтому начинаем с инвентаризации того, что уже работает, и только затем предлагаем схему статусов и порядок внедрения.

  • Как сейчас задача попадает в очередь и где хранится её состояние: таблица в базе, кэш или отдельная служба очередей.
  • Разбит ли длительный процесс на шаги и можно ли заранее посчитать их общее число — от этого зависит, будет прогресс-бар честным или останется «крутилкой».
  • Как интерфейс узнаёт об изменениях: редкий опрос по таймеру, поток событий или постоянный канал связи.
  • Что считается нормой при закрытии вкладки, падении обработчика и повторном запуске — какие сценарии допустимы, а какие нужно исключить.
  • Сколько задач идёт одновременно и на какую глубину истории статусов рассчитывать.
  • Требования к интерфейсу: где показывается прогресс, нужна ли отмена и что видит пользователь при ошибке.
  • Ограничения окружения: доступы к стендам, регламент выкладки, можно ли менять схему данных на живой системе.

По этим ответам мы собираем схему статусов — от постановки в очередь до завершения, отмены и ошибки — и раскладываем внедрение на этапы с понятным порядком. Опишите задачу в том объёме, в котором она есть: вернёмся с оценкой, схемой статусов и планом работ.

Наши компетенции:

Последние работы

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1542
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1394
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1368
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1139
  • Разработка веб-сайта для компании ФИКСПЕР
    Разработка веб-сайта для компании ФИКСПЕР
    1060