docs: предложения P-1–P-3 по контракту из задачи 4.3; отметки Task 9 / 4.3
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
f7cbe968e1
commit
cfba21b615
@ -51,7 +51,7 @@
|
||||
|
||||
### Task 9: [4.3] `src/core/worker.py`
|
||||
|
||||
- [ ] `src/core/worker.py`: `on_request(msg)`: валидация → множество `job_id` в работе/обработано (LRU) → ack `processing` → очередь; рабочая корутина: S3 get → `Parser` → S3 put результата → конверт → publish; таблица ошибок D-5; `metrics.duration_ms`; запуск/остановка в lifespan при `NATS_ENABLED`; `/healthcheck.nats`; проверка: unit-тесты с фейками — сценарии spec (ack раньше результата, повторный запрос, NOT_IMPLEMENTED, FILE_READ_ERROR, SCHEMA_MISMATCH без ack, подмена парсера → `done`, повтор публикации)
|
||||
- [x] `src/core/worker.py`: `on_request(msg)`: валидация → множество `job_id` в работе/обработано (LRU) → ack `processing` → очередь; рабочая корутина: S3 get → `Parser` → S3 put результата → конверт → publish; таблица ошибок D-5; `metrics.duration_ms`; запуск/остановка в lifespan при `NATS_ENABLED`; `/healthcheck.nats`; проверка: unit-тесты с фейками — сценарии spec (ack раньше результата, повторный запрос, NOT_IMPLEMENTED, FILE_READ_ERROR, SCHEMA_MISMATCH без ack, подмена парсера → `done`, повтор публикации)
|
||||
|
||||
### Task 10: [4.4] `tests/integration/test_roundtrip.py` (маркер `integration`)
|
||||
|
||||
|
||||
47
openspec/changes/slice-0-skeleton/open-questions-proposal.md
Normal file
47
openspec/changes/slice-0-skeleton/open-questions-proposal.md
Normal file
@ -0,0 +1,47 @@
|
||||
# Предложения по открытым вопросам и контракту (из реализации `slice-0-skeleton`)
|
||||
|
||||
Файлы `../docs` этот репозиторий не меняет: здесь — предложения для `docs/context/07-open-questions.md` и
|
||||
`docs/contracts/`; решение принимает человек / контроллер docs.
|
||||
|
||||
## P-1. Невалидный запрос без читаемых `job_id` / `file_id` / `attempt` (задача 4.3)
|
||||
|
||||
**Что видно в коде.** D-5 и spec требуют на запрос, не прошедший схему, ответить конвертом `error SCHEMA_MISMATCH`
|
||||
«если `job_id` читаем». Но `recognition-result-message.schema.json` требует ещё `file_id`, а `Nats-Msg-Id` результата —
|
||||
`result:<job_id>:<attempt>`. Если хоть одно из трёх не читается (тело не JSON, не объект, `job_id`/`file_id` не uuid,
|
||||
`attempt` нет ни в теле, ни в заголовке запроса `Nats-Msg-Id = <job_id>:<attempt>`), валидный конверт собрать нельзя.
|
||||
|
||||
**Как сделано сейчас.** Значения не выдумываются: запрос логируется уровнем error (`error_category=schema_mismatch`,
|
||||
причина, размер тела) и отбрасывается без ack и без результата. Ядро без ack повторит запрос `OUTBOX_MAX_REPUBLISH`
|
||||
раз и переведёт задание в `dlq` — то есть «молчание» сервиса превращается в `dlq` на стороне ядра.
|
||||
`attempt` при невалидном значении в теле берётся из заголовка запроса.
|
||||
|
||||
**Предложение.** Записать это в контракт явно (раздел «Сообщение не по схеме»): «если `job_id`, `file_id` или
|
||||
`attempt` не читаемы, сервис логирует ошибку и не отвечает; ядро обнаружит задание по `dlq`/`timeout`». Альтернатива —
|
||||
сделать `file_id` необязательным в конверте `error` (MINOR 1.1) — выглядит избыточной: ядро всегда шлёт корректные
|
||||
идентификаторы, нечитаемое тело — это сбой транспорта, а не данных.
|
||||
|
||||
## P-2. Противоречие: ack при несовместимой версии запроса (`schema_version = "2.0"`)
|
||||
|
||||
- `docs/openspec/changes/slice-0-skeleton/specs/recognition-contract/spec.md`, сценарий «Несовместимая версия запроса»:
|
||||
«публикуется результат `SCHEMA_MISMATCH`, **запрос подтверждается (ack)**, чтобы не зациклить доставку».
|
||||
- `openspec/changes/slice-0-skeleton/specs/tabular-recognition-service/spec.md` (этот репозиторий), сценарий
|
||||
«Несовместимая версия»: «публикуется конверт `SCHEMA_MISMATCH`, **ack не публикуется**»; D-5 — так же.
|
||||
|
||||
**Как сделано сейчас.** По спеке этого репозитория и брифу задачи: без ack, только результат `error SCHEMA_MISMATCH`.
|
||||
Зацикливания нет: ядро (`arm-core`, `recognition_exchange`) принимает результат и в статусе `published` («потерянный
|
||||
ack не блокирует результат») и закрывает задание, повторов не будет.
|
||||
|
||||
**Предложение.** Привести сценарий контракта в docs к «ack не публикуется; результат `SCHEMA_MISMATCH` закрывает
|
||||
задание» (или наоборот — тогда правка одной ветки в `worker.py`). Нужно решение человека.
|
||||
|
||||
## P-3. Повторная попытка (`attempt + 1`) того же `job_id` после ошибки (задача 4.3)
|
||||
|
||||
**Как сделано сейчас.** Дедупликация — по `job_id` (spec: «уже обрабатывается или обработан этим процессом»), любой
|
||||
итог (в том числе `error` и неудачная публикация результата) считается «обработан». Повторный запрос того же `job_id`
|
||||
с другим `attempt` в этом процессе получает только ack `ack:<job_id>:<attempt нового запроса>`, без обработки, пока
|
||||
`job_id` не вытеснен из LRU (`DONE_CACHE_SIZE`). Другая инстанция queue group обработает его как новый.
|
||||
|
||||
**Вопрос.** Если ядро (Срез 3+, replay/«переотправить») будет повторять задание тем же `job_id` с `attempt + 1`, ключ
|
||||
дедупликации должен стать `(job_id, attempt)`. Предложение: зафиксировать в контракте, что новая попытка — это новый
|
||||
`attempt` и сервис обрабатывает её заново; тогда в воркере ключ LRU меняется на `(job_id, attempt)` (одна строка).
|
||||
Пока ядро повторяет только тем же `attempt` (повтор без ack), текущее поведение корректно.
|
||||
@ -38,7 +38,7 @@
|
||||
подключение (с/без nkeys, автопереподключение), `subscribe_requests(queue="tabular-parser", cb)`,
|
||||
`publish(subject, payload, msg_id)` с повторами; проверка: unit-тесты с фейковым соединением; интеграционный тест
|
||||
подключения к compose-NATS без JetStream и получения сообщения с заголовком
|
||||
- [ ] 4.3 `src/core/worker.py`: `on_request(msg)`: валидация → множество `job_id` в работе/обработано (LRU) → ack `processing`
|
||||
- [x] 4.3 `src/core/worker.py`: `on_request(msg)`: валидация → множество `job_id` в работе/обработано (LRU) → ack `processing`
|
||||
→ очередь; рабочая корутина: S3 get → `Parser` → S3 put результата → конверт → publish; таблица ошибок D-5;
|
||||
`metrics.duration_ms`; запуск/остановка в lifespan при `NATS_ENABLED`; `/healthcheck.nats`; проверка: unit-тесты с
|
||||
фейками — сценарии spec (ack раньше результата, повторный запрос, NOT_IMPLEMENTED, FILE_READ_ERROR, SCHEMA_MISMATCH без
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user