- рядом с воркером свёртки живёт горутина, раз в минуту разбирающая журнал пассивным чекпойнтом; «журнал не разбирается» видно строкой владельцу, а не только по `df`. Признак — пара чисел, а не флаг занятости: тот молчит под удерживаемым читателем (`busy=0` при 6256 страницах и пяти перенесённых), а при занятой блокировке отдаёт `-1` вместо ответа, и `-1 >= -1` читалось бы как «разобрано целиком» - каталог отвечает `304` на `If-None-Match`, не открывая снимок витрины. Метка собрана из всего, от чего зависит ответ: версии витрины (`data_version` с закреплённого соединения плюс поколение — значение локально для соединения и не переживает переоткрытия), горизонта измерения и области действия ресурса. Версия снимается до и после сборки: снятая после пометила бы устаревший снимок свежим номером - предел и дедлайн ответа отложены в задачу Read API точек вместе с измеренной ценой первого запроса; попутно починен флаки-тест чужой задачи, искавший значение точки в сыром буфере записи лога
31 lines
1.7 KiB
Go
31 lines
1.7 KiB
Go
package catalog
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// Ответ каталога есть функция снимка И горизонта измерения: метка из будущего,
|
|
// лежащая в витрине, въезжает в окно сама, с ходом часов и без единого коммита.
|
|
// Построено враждебным проходом: та же версия витрины, `cumulative` против
|
|
// `unknown`. Значит горизонт обязан входить в метку — иначе клиент с
|
|
// `If-None-Match` получит `304` на изменившийся ответ.
|
|
func TestГоризонтВходитВВерсиюОтвета(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
at := time.Date(2026, 6, 1, 10, 30, 0, 0, time.UTC)
|
|
|
|
if stamp("v", at) == stamp("v", at.Add(2*time.Hour)) {
|
|
t.Error("версия не изменилась при сдвиге горизонта на два часа")
|
|
}
|
|
// Огрубление до часа точное, а не приблизительное: `hour_utc` объектов лежит
|
|
// ровно на часах, поэтому отбор меняется ровно при переходе через час.
|
|
// Внутри часа метка обязана стоять — иначе она дребезжала бы ежесекундно.
|
|
if stamp("v", at) != stamp("v", at.Add(20*time.Minute)) {
|
|
t.Error("версия сдвинулась внутри одного часа — метка дребезжит на месте")
|
|
}
|
|
if stamp("", at) != "" {
|
|
t.Error("пустая версия витрины подписана горизонтом — подписывать нечем")
|
|
}
|
|
}
|