Problem
DiagnosticsCollector.getReport()는 모든 provider의 getHealth()를 Promise.allSettled로 기다리지만 timeout이나 abort contract가 없습니다. 하나의 provider가 resolve/reject하지 않으면 전체 diagnostics report가 무기한 대기할 수 있습니다.
Evidence
packages/diagnostics-core/src/libs/DiagnosticsCollector.ts:40-45는 provider.getHealth()를 그대로 Promise.allSettled에 넘깁니다.
packages/diagnostics-core/src/libs/DiagnosticsCollector.ts:47-65는 reject는 degraded component로 변환하지만, pending 상태는 처리할 수 없습니다.
health-core와 transports-http에는 별도 timeout 패턴이 있어 diagnostics-core만 운영 엔드포인트에 취약한 모양입니다.
Desired Outcome
진단 report는 느리거나 멈춘 provider 하나 때문에 전체가 멈추지 않아야 하며, timeout된 provider는 degraded 상태로 기록되어야 합니다.
Suggested Approach
- collector-level default timeout과 provider-level override를 도입합니다.
- timeout 시 component status를
degraded로 기록하고 message에 timeout 원인을 포함합니다.
- 가능하면
AbortSignal을 provider contract에 추가하거나 optional로 전달합니다.
Acceptance Criteria
- pending provider가 있어도
getReport()는 설정된 시간 안에 반환합니다.
- timeout provider는 report components에 degraded로 포함됩니다.
- timeout 동작이 fake timer 테스트로 검증됩니다.
Validation
pnpm test --filter=@croco/diagnostics-core
- hanging provider regression test
Problem
DiagnosticsCollector.getReport()는 모든 provider의getHealth()를Promise.allSettled로 기다리지만 timeout이나 abort contract가 없습니다. 하나의 provider가 resolve/reject하지 않으면 전체 diagnostics report가 무기한 대기할 수 있습니다.Evidence
packages/diagnostics-core/src/libs/DiagnosticsCollector.ts:40-45는provider.getHealth()를 그대로Promise.allSettled에 넘깁니다.packages/diagnostics-core/src/libs/DiagnosticsCollector.ts:47-65는 reject는 degraded component로 변환하지만, pending 상태는 처리할 수 없습니다.health-core와transports-http에는 별도 timeout 패턴이 있어 diagnostics-core만 운영 엔드포인트에 취약한 모양입니다.Desired Outcome
진단 report는 느리거나 멈춘 provider 하나 때문에 전체가 멈추지 않아야 하며, timeout된 provider는 degraded 상태로 기록되어야 합니다.
Suggested Approach
degraded로 기록하고 message에 timeout 원인을 포함합니다.AbortSignal을 provider contract에 추가하거나 optional로 전달합니다.Acceptance Criteria
getReport()는 설정된 시간 안에 반환합니다.Validation
pnpm test --filter=@croco/diagnostics-core