web-ui: карточка и страница обновляются, пока задачу может двигать фон
- условие самообновления — доменный предикат store.State.IsObservable() вместо фазы catched; один поллер на поверхность, интервалы 5 с и 15 с - отказ тика отвечает 200 и самозавершающимся фрагментом с корневым id цели вместо 404/500, который htmx не свопит - заведён ADR-2026-08-10-observability-is-not-terminality, переписан раздел «Живой поллинг» в конвенции веб-UI
This commit is contained in:
@@ -21,7 +21,8 @@ type downloadDetailView struct {
|
||||
Infohashes []string // все хеши загрузки (блок «Информация о торренте»)
|
||||
Context string
|
||||
State string
|
||||
SelfPoll bool // catched → страница сама опрашивает себя до перехода
|
||||
SelfPoll bool // задача наблюдаема → страница сама опрашивает себя
|
||||
PollEvery string
|
||||
Error string
|
||||
ActionError string // ошибка действия на htmx-пути (своп download_main), не error_msg
|
||||
Note string
|
||||
@@ -89,6 +90,15 @@ func (s *server) handleDownload(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
rd, err := s.deps.Reviewer.ReviewData(r.Context(), id)
|
||||
if err != nil {
|
||||
// Тик самообновления страницы идёт этим же маршрутом (hx-get="/download/{id}"
|
||||
// с hx-select="#download-main"). Отвечать ему статусом ошибки нельзя: htmx не
|
||||
// свопит 4xx/5xx и не снимает hx-trigger — страница осталась бы навсегда
|
||||
// устаревшей, а опрос продолжался бы до закрытия вкладки. Навигационный GET
|
||||
// (адресная строка, закладка) по-прежнему получает честный статус.
|
||||
if isHTMX(r) {
|
||||
s.fragTickErr(w, err, id, "download-main")
|
||||
return
|
||||
}
|
||||
if errors.Is(err, store.ErrNotFound) {
|
||||
http.Error(w, "задача не найдена", http.StatusNotFound)
|
||||
return
|
||||
@@ -113,7 +123,10 @@ func (s *server) buildDownloadView(id string, rd *worker.ReviewData) downloadDet
|
||||
Infohashes: d.HashList(),
|
||||
Context: d.Context,
|
||||
State: string(d.State),
|
||||
SelfPoll: d.State == store.StateCatched,
|
||||
SelfPoll: d.State.IsObservable(),
|
||||
// Блока живых цифр качания на странице нет вовсе, а тик считает
|
||||
// предпросмотр раскладки и ходит в ФС — интервал всегда медленный.
|
||||
PollEvery: pollSlow,
|
||||
Error: d.ErrorMsg.String,
|
||||
Note: desyncNote(d.State),
|
||||
CreatedAt: d.CreatedAt,
|
||||
|
||||
Reference in New Issue
Block a user