diff --git a/troubleshooting/251022_claude_rb8001_email_422_and_grpc_loop_fix.md b/troubleshooting/251022_claude_rb8001_email_422_and_grpc_loop_fix.md new file mode 100644 index 0000000..b4ba7f1 --- /dev/null +++ b/troubleshooting/251022_claude_rb8001_email_422_and_grpc_loop_fix.md @@ -0,0 +1,53 @@ +# rb8001: skill-email 422 대응 및 gRPC Poller 오류 완화 + +**날짜**: 2025-10-22 +**작성자**: Claude (51124 서버 전담) +**범위**: rb8001 컨테이너(Dockerfile/Router/Logger), 스크립트 내 이메일 URL 정합성 + +--- + +## 문제 요약 +- 422 Unprocessable Entity (skill-email): rb8001이 `/send`로 자연어 payload를 전달하여 스키마 불일치(422) 다수 발생. +- gRPC Poller 오류 노이즈: 매일 09:00 전후 `asyncio` 모듈에서 `PollerCompletionQueue ... BlockingIOError [Errno 11]` 로그 반복. +- 참고: LLMRequest `task_type` 검증오류는 2025-10-21 커밋(69e201c, c9b90f8)에서 해결됨(재확인). + +## 원인 +- 이메일: Router가 이메일 스킬을 일반 HTTP 프록시로 `/send`에 직결(자연어 message + execution_plan 포함) → skill-email 기대 스키마(to/subject/body/user_id)와 불일치. +- Poller 오류: uvicorn[standard]가 uvloop를 기본 사용 → gRPC와 이벤트 루프 경합으로 `asyncio` ERROR 로그 발생. + +## 조치 (코드) +- uvloop 비활성화(uvicorn): `--loop asyncio` 지정 + - 파일: `rb8001/Dockerfile:33` + - 변경: `python -m uvicorn ... --loop asyncio` + +- 이메일 라우팅을 통합 모듈로 경유: + - 파일: `rb8001/app/router/router.py:~180` + - 변경: `SkillType.EMAIL` 시 `email_integration.process_email_request()` 호출로 전환 → skill-email `/process`로 안전 호출(자연어 입력/UUID 포함, 내부 헤더/힌트 포함). + +- 하드코딩된 email URL 제거 → `SKILL_EMAIL_URL` 사용 일원화: + - 파일: `rb8001/app/skills/dm_skill.py:...`, `rb8001/scripts/find_coldmail_candidates.py:...`, + `rb8001/scripts/find_pdf_emails.py:...`, `rb8001/scripts/debug_email_detail.py:...` + +- Poller 노이즈 필터 추가: + - 파일: `rb8001/app/core/logger.py:~36` + - 내용: `asyncio` 로거에 `PollerCompletionQueue + BlockingIOError` 메시지 필터 추가(안전한 억제). + - 기존 gRPC/asyncio 레벨 조정 유지. + +## 배포/검증 +1) 배포: `docker compose down && docker compose up -d --build` (rb8001) +2) 헬스: `curl http://localhost:8001/health` = 200 +3) 이메일 시나리오: “메일 보내줘 …” + - 기대: 422 미발생, skill-email `/process` 호출 로그 200 +4) Poller 로그: 09:00 이후 `BlockingIOError` 미출력 확인(필요 시 OpenSearch UTC→KST 변환 확인) +5) 스크립트: 각 스크립트에서 `SKILL_EMAIL_URL` 사용 확인 + +## 결과 +- 422 감소: 이메일 경로가 통합 모듈을 경유하면서 스키마 불일치로 인한 422 제거/감소. +- Poller ERROR 억제: uvloop 비활성화 + 필터로 운영 로그 노이즈 완화. +- 구성 정합성: 하드코딩 제거로 환경변수 기반 동작 일관성 확보. + +## 교훈 ✍️ +- 스킬 연동은 “게이트웨이/통합 모듈”로 수렴해 계약(API 스키마)을 강제. +- uvloop 같은 성능 최적화는 의존성(gRPC) 호환성 검증 후 단계적 적용. +- 환경변수 일원화로 컨테이너/로컬/서버 간 구동 차이를 최소화. +