Приём отвечает 200 до свёртки, свёртку ведёт фоновый воркер
- Очередью служит сама таблица: доставка ждёт свёртки в статусе `pending`, канал несёт только бит «есть работа». Переполнять нечего, падение процесса очередь не теряет, а подбор `pending` при старте — обычный проход воркера, а не отдельный код. Классификация исхода общая с пересборкой журнала. - Исход разбора начал отражать доставку, а не обстоятельства: отмена и занятость базы статус не меняют (иначе конкуренция за базу выводила бы доставку из очереди навсегда), паника свёртки больше не валит процесс, а учёт доставки идёт через транзакцию с повторами. - Длинный бюджет ответа выдан маршруту приёма, а не всему серверу: `write_timeout` в Go покрывает и чтение тела, и общий подъём снял бы защиту с остальных маршрутов.
This commit is contained in:
@@ -324,3 +324,65 @@ func TestFoldПересвёрткаОчищаетСписок(t *testing.T) {
|
||||
t.Errorf("статус %q, ожидался %q", d.ParseStatus, store.ParseDone)
|
||||
}
|
||||
}
|
||||
|
||||
// Отмена снаружи не превращается в свойство доставки: работа не сделана, но
|
||||
// доставка остаётся в очереди и будет свёрнута снова. Иначе остановка сервиса в
|
||||
// неудачный момент выводила бы доставку из очереди навсегда — `failed` фоновая
|
||||
// свёртка не подбирает никогда, и вернуть её могла бы только пересборка с
|
||||
// остановкой сервиса и ручной подменой базы.
|
||||
func TestFoldОтменаОставляетДоставкуВОчереди(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
f, arch, st := newFold(t)
|
||||
deliver(t, arch, st, "d1", "Minutes", "auto-1", fixture(t, "minute.json"))
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
cancel()
|
||||
|
||||
if _, err := f.Fold(ctx, "d1"); err == nil {
|
||||
t.Fatal("свёртка на отменённом контексте прошла успешно")
|
||||
}
|
||||
|
||||
status, err := st.DeliveryStatus(context.Background(), "d1")
|
||||
if err != nil {
|
||||
t.Fatalf("DeliveryStatus: %v", err)
|
||||
}
|
||||
if status != store.ParsePending {
|
||||
t.Errorf("parse_status = %q, ожидался %q", status, store.ParsePending)
|
||||
}
|
||||
|
||||
n, err := st.CountBuckets(context.Background())
|
||||
if err != nil {
|
||||
t.Fatalf("CountBuckets: %v", err)
|
||||
}
|
||||
if n != 0 {
|
||||
t.Errorf("объектов %d: прерванная свёртка оставила половину", n)
|
||||
}
|
||||
}
|
||||
|
||||
// Непонятое содержимое, наоборот, свойство самой доставки: повторять её
|
||||
// бесполезно, и она выводится из очереди.
|
||||
func TestFoldНепонятоеСодержимоеВыводитИзОчереди(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
f, arch, st := newFold(t)
|
||||
ctx := context.Background()
|
||||
|
||||
// Метрика есть, но слой определить нечем: плотных метрик нет, заголовок
|
||||
// ничего не означает, наследовать не от чего.
|
||||
body := []byte(`{"data":{"metrics":[{"name":"m","units":"u","data":[` +
|
||||
`{"date":"2026-07-31 12:00:00 +0300","qty":1}]}]}}`)
|
||||
deliver(t, arch, st, "d1", "Default", "auto-1", body)
|
||||
|
||||
if _, err := f.Fold(ctx, "d1"); err == nil {
|
||||
t.Fatal("свёртка непонятого содержимого прошла успешно")
|
||||
}
|
||||
|
||||
status, err := st.DeliveryStatus(ctx, "d1")
|
||||
if err != nil {
|
||||
t.Fatalf("DeliveryStatus: %v", err)
|
||||
}
|
||||
if status != store.ParseFailed {
|
||||
t.Errorf("parse_status = %q, ожидался %q", status, store.ParseFailed)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user