커머스 검색요청 계약을 프레임워크(protocol+service+RemoveNoneResponse)로 재구성.
실제 검색은 워커가 큐에서 꺼내 수행하도록 API 는 적재까지만 담당(비동기 분리).
- POST /v1/lps/search: 상품 리스트 → 상품별 SEARCH 잡 적재, product_code 로 활성 중복 방지, job_type→우선순위 매핑
- GET /v1/lps/jobs/{job_id}: 잡 상태/시도/결과 조회
- GET /v1/lps/queue/stats: 상태별 카운트(모니터링)
- protocol/lps_service 추가, job_crud.get() 단건조회, enums LPS_JOB_NOT_FOUND
- tests: 적재/중복/상태/미존재/통계 5건 (ASGI 클라이언트 + 실 lps_db) → 전체 16/16
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
72 lines
2.7 KiB
Python
72 lines
2.7 KiB
Python
from enum import Enum, auto
|
|
|
|
from fastapi import HTTPException
|
|
|
|
|
|
class ErrorType(Enum):
|
|
"""서버 전역 결과 코드. Res_WebPacketProtocol.result 에 담겨 클라이언트로 전달된다.
|
|
HTTP status 와 겹치지 않도록 구간을 분리해서 관리한다.
|
|
도메인 로직이 생기면 각 구간(예: 1500~ LPS 전용)을 이어서 추가한다.
|
|
"""
|
|
|
|
SUCCESS = 0
|
|
FAIL = 1
|
|
|
|
# DB 에러
|
|
DB_RUN_FAILED = 10
|
|
DB_ALREADY_SAME_KEY = auto()
|
|
DB_INVALID_KEY = auto()
|
|
DB_EMPTY_DATA = auto()
|
|
DB_INVALID_TYPE = auto()
|
|
|
|
# 요청/직렬화 에러
|
|
JSON_PARSE_ERROR = 100
|
|
INVALID_REQUEST_DATA = auto()
|
|
INTERNAL_EXCEPTION = auto()
|
|
|
|
# http 에러 코드와 겹치지 않게 설정 - router 전용 예외 발생 옵션
|
|
HTTP_INVALID_CLIENT_REQUEST = 419
|
|
HTTP_TO_MANY_REQUEST = 429
|
|
HTTP_INVALID_CLIENT_ACCESS = 433
|
|
|
|
# LPS 도메인 에러 (1500~)
|
|
LPS_JOB_NOT_FOUND = 1500 # 잡 없음/잘못된 job_id
|
|
|
|
|
|
# ErrorType 의 HTTP_* 값과 status_code 를 맞춰 router 단에서 raise 한다.
|
|
EXCEPTION_INVALID_CLIENT_REQUEST = HTTPException(status_code=ErrorType.HTTP_INVALID_CLIENT_REQUEST.value, detail=ErrorType.HTTP_INVALID_CLIENT_REQUEST.name)
|
|
EXCEPTION_TO_MANY_REQUEST = HTTPException(status_code=ErrorType.HTTP_TO_MANY_REQUEST.value, detail=ErrorType.HTTP_TO_MANY_REQUEST.name)
|
|
EXCEPTION_INVALID_CLIENT_ACCESS = HTTPException(status_code=ErrorType.HTTP_INVALID_CLIENT_ACCESS.value, detail=ErrorType.HTTP_INVALID_CLIENT_ACCESS.name)
|
|
|
|
|
|
class DBType(Enum):
|
|
"""논리 DB 식별자. 물리적으로 같은 DB 라도 도메인별로 논리 구분한다.
|
|
DB 가 늘어나면 여기에 추가하고 db_session_manager 의 엔진 맵에도 등록한다.
|
|
"""
|
|
|
|
MAIN = 1 # LPS 기본 DB
|
|
|
|
|
|
class DBWRType(Enum):
|
|
"""Read/Write 분리. 조회는 READ(복제), 변경은 WRITE(주 DB)."""
|
|
|
|
DB_READ = 1
|
|
DB_WRITE = 2
|
|
|
|
|
|
class JobStatus(Enum):
|
|
"""작업 큐 상태. 전이는 전부 조건부 원자 UPDATE(CAS)로만 한다.
|
|
실패는 재시도 가능하면 PENDING(run_after=백오프)으로 되돌리고, 소진되면 DEAD(dead-letter)."""
|
|
|
|
PENDING = 1 # 대기(claim 가능). run_after <= now() 일 때만 실제 claim 대상
|
|
RUNNING = 2 # 워커가 점유 중(lease_until 까지 소유). 만료 시 reaper 가 회수
|
|
DONE = 3 # 완료
|
|
DEAD = 4 # dead-letter — max_attempts 소진(수동 개입/알림 대상)
|
|
|
|
|
|
class JobType(Enum):
|
|
"""작업 종류. 무거운 잡(SEARCH=브라우저)과 가벼운 잡을 구분해 워커/동시성을 분리한다."""
|
|
|
|
SEARCH = 1 # 최저가 검색(쿠팡=브라우저) — 무거움
|
|
OUTBOX = 2 # 외부 API 결과 전송(재시도 엔진 공유) — 가벼움
|