4.5 KiB
id, status
| id | status |
|---|---|
| ac-0040 | active |
Ledger outbox idle poll 로그 억제와 운영 metric
Criterion
Ledger outbox writer는 pending row가 없는 poll마다 instance-local process-lifetime empty poll counter를 정확히 증가시키되 empty claim INFO를 생성하지 않아야 한다. non-empty batch claim은 configured instance_key, non-zero count, limit, 해당 batch의 non-empty correlation ID를 repository claim 순서와 동일한 correlation_ids JSON string array로 INFO에 남겨야 한다. empty poll은 claim INFO 자체를 생성하지 않으므로 correlation_ids field도 출력하지 않는다.
trex.slots.req의 spy=true 응답은 top-level ledger_outbox_metrics를 포함해야 한다. 정상 snapshot은 available=true, scope=process_lifetime, configured instance_key를 포함하고, claims object에서 empty_polls_total, claimed_batches_total, unavailable_total, lost_total, foreign_instance_total을, outcomes object에서 completed_total, duplicate_completed_total, retryable_failure_total, conflict_blocked_total, permanent_failure_total, dead_lettered_total을 각각 누락 없는 0 이상의 정수로 제공해야 한다. snapshot은 해당 daemon process의 configured instance writer만 집계하고 내부 mutable counter와 분리된 새 값이어야 한다. reader가 없거나 조회가 실패하면 available=false, scope=process_lifetime, configured instance_key, reason=ledger_outbox_metrics_unavailable만 포함한 snapshot을 반환하며 slots 조회 자체는 성공해야 한다. spy=false 응답에는 ledger_outbox_metrics key를 포함하지 않아야 한다.
TrexDaemon._ledger_loop()에서 writer가 예상 밖 예외를 던지면 reason=ledger_writer_run_once_failed, configured instance_key, exception class name인 exc_type만 ERROR로 남기고 다음 configured poll을 계속해야 한다. empty/non-empty/failure 관측 어디에도 credential, account identifier, token, password, DSN, provider payload, raw exception message, traceback 또는 exc_info가 포함되어서는 안 된다. fixed polling cadence, retry scheduling, claim lease, ownership/filtering과 기존 outcome 의미는 바뀌지 않아야 한다.
Verification
- 성공 조건: 기본
ledger_interval_sec=1.0의 24시간에 해당하는 86,400회 emptyrun_once()를 실제 sleep 없이instance-a와instance-bwriter에 각각 실행했을 때 각empty_polls_total이 정확히 86,400이고 rendered INFO의claim_result=empty및correlation_ids가 0건인지 확인한다. 한 개 이상의 item을 claim하면 batch INFO에 configured instance, non-zero count, limit와 repository claim 순서 그대로인correlation_idsJSON string array가 있고claimed_batches_total및 처리 outcome totals가 맞는지 확인한다. - 운영 조회 조건:
spy=true에서 정상 schema의 모든 key와 zero/default 정수, instance/process 격리, 매 호출 새 snapshot을 확인한다. reader absent 및 reader exception에서는 stable unavailable snapshot과 slots 응답 성공을 확인한다.spy=false에는 metrics key가 없음을 확인한다. - 실패·보안 조건: sentinel secret을 포함한 writer exception을 두 번의 loop tick 중 첫 tick에 주입해 ERROR reason·instance·exception type, 두 번째 tick 실행, raw sentinel·exception message·traceback·
exc_info부재를 확인한다. 기존 claim-lost, foreign/unowned, retryable, conflict, permanent, dead-letter, success와 duplicate outcome의 severity·counter·상태 전이가 유지되는지 확인한다. - 변경 없음 조건:
AC-0029의 InMemory/PostgreSQL ownership, active lease exclusion, expiry recovery, stale-token fencing과 foreign/unowned isolation을 회귀 검증한다.ledger_interval_sec, retrynext_retry_at, DB schema, ledger API와 dead-letter policy의 diff가 없는지 확인한다. - 문서 조건:
docs/runtime-flows.md와docs/interface-contract.md가 empty claim INFO suppression, spy operator-only metrics, process-lifetime 및 restart-reset scope, fixed cadence 유지, sanitized writer exception과 loop survival을 명시하는지 직접 검사한다. - 검사 방법: focused writer·messaging handler·daemon unit tests, InMemory parity tests, disposable PostgreSQL multi-instance tests, 전체
pytest, Ruff,compileall,proofline validate,git diff --check를 실행한다. PostgreSQL fixture가 없어서 skip되면 통과로 치환하지 않고 환경 미검증으로 보고한다.