- страница /download/{id} держит бейдж «распознаётся» после перехода задачи
дальше; воспроизведено на боевом umbar на последней версии
- причина неизвестна: тик самообновления объявлен и покрыт тестом, поэтому
первый критерий приёмки — назвать, на каком шаге он теряется
5.3 KiB
🐞 Обновлять страницу загрузки при выходе из «распознаётся»
- Тип: fix
- Категория: Ядро продукта
- Зачем: на боевом umbar последней версии страница держит бейдж «распознаётся» после того, как задача ушла в review или done — состояние видно только по F5
Спека web-ui («Самообновление живой задачи») заказывает: страница наблюдаемой
задачи обновляет себя сама, пока задачу может двигать фон. recognizing
наблюдаем (State.IsObservable), тик страницы объявлен every 15s, и разметка
покрыта тестом TestDownloadPageSelfPoll — а на боевом стенде страница
застывает. Расходится не разметка, а поведение живой страницы, и причина
неизвестна: тик либо не уходит, либо уходит и не свопит, либо гасит сам себя.
Речь только о странице /download/{id}. Список загрузок ведёт свой поллер
(карточка опрашивает /fragments/downloads/{id}/card) и в эту задачу не входит:
на нём застывания не заявлено и оно не проверялось.
Воспроизведение
- Открыть
/download/{id}на боевом umbar, пока задача вrecognizing. - Дождаться, когда фон уведёт её дальше — в
reviewилиdone. - Смотреть на страницу, не трогая её.
Видно вместо ожидаемого: бейдж и вся главная область остаются на «распознаётся»
дольше одного тика (15 с) — сколько именно, не замерено. Нажатие F5 показывает
настоящее состояние сразу. Наблюдалось на umbar на последней выложенной версии,
то есть уже с самообновлением из коммита a5d873b.
Замера «через сколько секунд перестало обновляться», журнала сети из браузера и проверки на локальном запуске нет — первым делом их и надо снять.
Затрагивает
web/templates/partials/download_main.html— объявление тика:hx-get="/download/{id}",hx-trigger="every …",hx-select="#download-main",hx-swap="outerHTML"иhx-preserveна «Опасной зоне»;handleDownloadиbuildDownloadView(internal/httpapi/download.go) — ответ на тик, веткаisHTMX→fragTickErrи вычислениеSelfPoll/PollEvery;fragNote(internal/httpapi/live.go) — самозавершающийся фрагмент, который снимает поллер с поверхности;State.IsObservable(internal/store/download.go) — предикат, на котором стоит тик;- спеки
web-ui(«Самообновление живой задачи») иlive-status; - боевой рантайм: версия развёрнутого бинаря, раздача статики и заголовки
кэширования страницы
/download/{id}.
Критерии приёмки
- Причина названа и подтверждена: показано, на каком шаге тик теряется — запрос не уходит, ответ не свопится или поллер снят (оракул: журнал сети браузера или лог сервера с боевого стенда, приложенный к задаче).
- Страница, открытая в
recognizing, показывает новое состояние без F5 не позже двух тиков после перехода (оракул: ручной прогон на umbar с засечкой времени перехода по логу сервера и времени смены бейджа). - Найденная причина закрыта проверкой, которая падала бы до починки (оракул:
тест в
internal/httpapi; причина не ловится тестом — сказано прямо, чем она закрыта вместо теста). - Тик по-прежнему замолкает на ненаблюдаемом состоянии (оракул: существующий
TestDownloadPageSelfPollзелёный). task gateзелёный (оракул: сам гейт).
Рамки
На SSE не переезжать — это отдельная задача sse-live-updates; чинится
существующий htmx-поллинг. Ветку fragTickErr не убирать: она стоит там, чтобы
отказ чтения не оставлял вкладку стучать вечно (ADR-2026-08-10-observability-is-not-terminality).