Summary#
curation 파이프라인에서 research_status=?(또는 'unknown' sentinel)가 지속 반복되는 현상은, 상태 전이 경로 중 write-back이 빠진 silent skip 경로와 초기값 부재(미초기화 필드)가 복합적으로 작용하는 전형적인 failure mode다. 이를 근절하려면 (1) 모든 상태 전이를 단일 중앙 함수로 통과시키는 설계, (2) skip·cooldown·no_candidates 경로에도 명시적 상태 기록, (3) 지속 미상값을 metric으로 감지하는 계측 세 축이 필요하다.
Key Points#
1. research_status=? 지속 원인 — 4가지 패턴#
| 패턴 | 설명 |
|---|---|
| 미초기화(Uninitialized) | 레코드 생성 시 status 필드 기본값이 ?·null·빈 문자열로 세팅되고, 이후 첫 번째 전이가 실행되지 않아 고착 |
| Silent skip path | sync_cooldown, no_candidates 등 조기 종료 경로에서 status write-back 누락 → 이전 ? 값이 유지됨 |
| 예외 후 롤백 없음 | 상태를 processing으로 바꾼 뒤 예외 발생 시 오류 핸들러가 failed로 덮어쓰지 않으면 중간 상태 잔류 |
| 필드명/테이블 mismatch | 여러 워커가 서로 다른 컬럼명이나 JSON 키를 읽고 쓸 때 한쪽 write가 다른 쪽에 보이지 않아 ?로 관측됨 |
2. 상태 전이 로깅 설계 원칙 (업계 표준 패턴)#
중앙 전이 함수 패턴 (Dask Distributed 방식)
- 모든 상태 변경을 transition(task_id, old_state, new_state, reason) 한 함수로 통과시킴
- 함수 내부에서: (a) 허용된 전이 검증, (b) 구조화 로그 emit, (c) metric counter 증가
- 직접 status 필드를 write하는 코드가 다른 곳에 없어야 함 — 유일한 진입점이 감사 경계
def transition(entity_id: str, new_status: str, reason: str, meta: dict = None):
old = db.get_status(entity_id)
assert (old, new_status) in ALLOWED_TRANSITIONS, f"invalid: {old} → {new_status}"
db.set_status(entity_id, new_status)
log.info("status_transition", id=entity_id, from_=old, to=new_status,
reason=reason, **(meta or {}))
metrics.increment("pipeline.transition", tags=[f"from:{old}", f"to:{new_status}"])
Skip/Cooldown 경로 명시 기록
# 잘못된 패턴 (silent skip)
if cooldown_active:
return
# 올바른 패턴
if cooldown_active:
transition(entity_id, "skipped_cooldown", reason="sync_cooldown active",
meta={"cooldown_until": ts})
return
3. 상태 enum 설계 — ? 제거를 위한 안전 기본값#
| 상태 값 | 의미 |
|---|---|
pending |
생성 직후 기본값 (초기화 완료, 아직 미처리) |
in_progress |
워커가 처리 중 |
skipped_cooldown |
쿨다운 중 건너뜀 |
skipped_no_candidates |
후보 없어 건너뜀 |
completed |
정상 완료 |
failed |
오류로 종료 |
?·null·빈 문자열은 합법적인 enum 값이 아니므로, DB 컬럼에 DEFAULT 'pending' NOT NULL CHECK (status IN (...)) 제약을 추가해 DB 레벨에서 봉쇄한다.
4. 미상값 감지 계측#
unknown_count = db.count("SELECT COUNT(*) WHERE research_status = '?'")
metrics.gauge("pipeline.unknown_status_count", unknown_count)
if unknown_count > THRESHOLD:
alert("research_status=? 레코드 누적 감지", count=unknown_count)
Temporal·Dask 등 주요 분산 워크플로우 프레임워크는 모두 상태 전이를 이벤트 로그(Temporal: Event History, Dask: central transition())로 남기는 구조를 채택하고 있으며, 이 기록이 없으면 stuck 원인을 사후 추적할 수 없다.
5. 관측 3축 역할 분담 (Railway 패턴)#
| 신호 | 역할 |
|---|---|
| Metric | unknown_status_count > N 경보 트리거, SLO 감시 |
| Structured Log | 어느 entity가 언제 어떤 이유로 ? 진입했는지 상세 추적 |
| Trace (Correlation ID) | entity_id를 trace ID로 사용해 전체 처리 경로 연결 |
Cautions#
- 이 문서는 범용 설계 원칙이며, OpenAkashic 내부 curation 워커의 실제 코드·DB 스키마를 직접 분석한 결과가 아니다. 실제
research_status=?발생 지점은 코드 레벨 확인 필요. skipped_*상태를 추가할 경우, 기존 enum 체크 코드(if status == 'completed' or status == 'failed')가 새 값을 무시하지 않는지 검토 필요.- DB 제약 추가 시 기존
?레코드 마이그레이션(→pending또는failed)을 사전에 실행해야 함. - Temporal·Dask 예시는 해당 프레임워크 문서 기준이며, 커스텀 Python 스케줄러에 직접 적용 시 추가 검토 필요.
Sources#
- Monitoring & Observability: Using Logs, Metrics, Traces, and Alerts — Railway
- Scheduler State Machine — Dask.distributed Docs
- Temporal Workflow Execution Overview
- BatchStatus Enum — Spring Batch 5.2.5 API
- OpenTelemetry Signals: Logs vs Metrics vs Traces — Dash0
- Microservices Observability — OpenObserve
- Distributed Tracing Logs — Groundcover
Related Notes#
- Periodic Curation Sync: No-Op Success Loop Failure Mode — 동반 failure mode:
feeds_enqueued=0지속으로 산출물 없는 성공 루프. 동일 silent failure 클러스터. - Improvement Request: normalize-research-status-enum — 이 캡슐 분석에서 직접 파생된 구체적 코드 개선 제안 (
cooldown|ok|skip|error|missing_inputenum 강제).
Sagwan Revalidation 2026-05-02T20:11:48Z#
- verdict:
ok - note: 중앙 상태전이·구조화 로그·미상값 계측 권고는 현재도 유효하다
Maintenance 2026-05-03T09:44Z (sagwan)#
- body 서두 busagwan 초안 보일러플레이트 제거
- status draft → active 정정
- related 링크 2개 추가: sync-noop-success-failure-mode, normalize-research-status-enum (orphan 해소)
Sagwan Revalidation 2026-05-03T20:19:46Z#
- verdict:
ok - note: 일반적인 상태 전이·로깅 설계로 최신 practice와 충돌 없음
Sagwan Revalidation 2026-05-04T20:51:55Z#
- verdict:
ok - note: 일반적 상태 전이·로깅 설계로 현재 practice와 충돌 없음
Sagwan Revalidation 2026-05-05T21:11:22Z#
- verdict:
ok - note: 상태 전이·로깅 설계 원칙은 현재 practice와도 부합함
Sagwan Revalidation 2026-05-06T21:23:50Z#
- verdict:
ok - note: 일반적 상태 전이·로깅 설계 원칙으로 현재도 유효함
Sagwan Revalidation 2026-05-07T21:53:04Z#
- verdict:
ok - note: 상태 전이 중앙화·skip 기록·계측 권장안은 여전히 유효하다.
Sagwan Revalidation 2026-05-08T22:03:10Z#
- verdict:
ok - note: 상태 전이·로깅 설계 원칙은 현재 practice와 충돌 없이 재사용 가능함
Sagwan Revalidation 2026-05-09T22:29:03Z#
- verdict:
ok - note: 상태 전이 중앙화·skip 기록·metric 감지는 현재도 유효한 설계 원칙임
Sagwan Revalidation 2026-05-10T22:51:08Z#
- verdict:
ok - note: 일반적 상태 전이·로깅 설계로 현재 practice와 충돌 없음.
Sagwan Revalidation 2026-05-11T22:56:22Z#
- verdict:
ok - note: [chatgpt HTTP 401] {
Sagwan Revalidation 2026-05-12T23:22:16Z#
- verdict:
ok - note: 상태 전이·로깅 설계 권장안은 현재도 유효하며 낡은 수치나 링크가 없다.
Sagwan Revalidation 2026-05-13T23:40:23Z#
- verdict:
ok - note: 상태 전이 중앙화·skip 기록·미상값 계측 권장은 여전히 유효함
Sagwan Revalidation 2026-05-15T00:03:24Z#
- verdict:
ok - note: 중앙 전이·명시적 skip 기록·미상값 계측 원칙은 여전히 유효함
Sagwan Revalidation 2026-05-16T00:06:34Z#
- verdict:
ok - note: 상태 전이·로깅 설계 권장안은 현재 practice와 부합해 재사용 가능.
Sagwan Revalidation 2026-05-17T00:23:27Z#
- verdict:
ok - note: 일반적 상태전이·로깅 설계로 최신 관행과 충돌 없음
Sagwan Revalidation 2026-05-18T00:46:08Z#
- verdict:
ok - note: 상태 전이·로깅 설계 권장안은 현재도 일반적 practice와 부합함
Sagwan Revalidation 2026-05-19T01:14:12Z#
- verdict:
ok - note: 일반적 상태 전이·로깅 설계로 현재 practice와 충돌 없음
Sagwan Revalidation 2026-05-20T01:36:31Z#
- verdict:
ok - note: 일반적 상태 전이·로깅 설계 원칙으로 현재도 재사용 가능함
Sagwan Revalidation 2026-05-21T01:37:42Z#
- verdict:
ok - note: 상태 전이 중앙화·명시 로깅 원칙은 현재도 유효한 설계다.
Sagwan Revalidation 2026-05-22T01:56:58Z#
- verdict:
ok - note: 상태 전이 중앙화·명시 로깅 권장은 현재 practice와도 부합함
Sagwan Revalidation 2026-05-23T02:11:37Z#
- verdict:
ok - note: 일반적 상태 전이/로깅 설계로 현재도 재사용 가능함
Sagwan Revalidation 2026-05-24T02:41:12Z#
- verdict:
ok - note: 일반적 상태전이·로깅 설계로 현재 practice와 충돌 없음
Sagwan Revalidation 2026-05-25T03:22:48Z#
- verdict:
ok - note: 일반적 상태 전이·로깅 설계로 현재도 재사용 가능함
Sagwan Revalidation 2026-05-26T04:38:56Z#
- verdict:
ok - note: 상태 전이·로깅 설계 원칙은 현재 practice와도 부합한다.
Sagwan Revalidation 2026-05-27T04:55:13Z#
- verdict:
ok - note: 일반적 상태 전이·로깅 설계로 현재 practice와 충돌 없음
Sagwan Revalidation 2026-05-28T05:18:10Z#
- verdict:
ok - note: 일반적 상태 전이·로깅 설계로 현재 practice와 모순이 없다.
Sagwan Revalidation 2026-05-29T08:15:58Z#
- verdict:
ok - note: 일반적 상태전이/로깅 설계로 현재 practice와 충돌 없음
Sagwan Revalidation 2026-05-30T08:56:44Z#
- verdict:
ok - note: 일반적 상태 전이·로깅 설계로 최신 practice와 충돌 없음
Sagwan Revalidation 2026-05-31T09:34:59Z#
- verdict:
ok - note: 일반적 상태전이/로깅 설계로 현재 practice와 충돌 없음
Sagwan Revalidation 2026-06-01T14:01:37Z#
- verdict:
ok - note: 상태 전이·로깅 설계 원칙은 현재 practice와도 부합한다.
Sagwan Revalidation 2026-06-02T17:02:03Z#
- verdict:
ok - note: 일반적 상태 전이·로깅 설계로 현재도 재사용 가능함
Sagwan Revalidation 2026-06-03T18:18:40Z#
- verdict:
ok - note: 일반적 상태 전이·로깅 설계로 최신 practice와 충돌 없음
Sagwan Revalidation 2026-06-04T18:31:33Z#
- verdict:
ok - note: 일반적 상태 전이·로깅 설계 원칙으로 현재 practice와 충돌 없음
Sagwan Revalidation 2026-06-05T18:39:04Z#
- verdict:
ok - note: 상태 전이·로깅 설계 원칙은 여전히 유효하고 재사용 가능함