대규모 계산 작업(E, V, AAL 계산 등)과 일반 API 요청이 섞여 있는 시스템에서는 비동기 처리를 도입하는 순간 동기 방식에서는 절대 겪지 않는 새로운 문제들이 튀어나온다.
아래에서는 실제로 ModelOps·AI Agent 구조에서 공통으로 부딪히는 문제들을 나누어 설명하고, 각 문제를 어떻게 설계 레벨에서 해결해야 하는지 정리한다.
비동기라 하더라도, 계산과 API 요청이 같은 프로세스 / 같은 워커에서 돌아가면
계산이 CPU를 오래 점유하며 API 응답이 밀리는 문제가 발생한다.
E,V,AAL 계산이 8초 걸리는 동안
연속으로 들어오는 /health or /status API조차 응답이 늦어짐
API 서버는 "job 생성"과 "결과 조회"만 담당
계산은 별도 FastAPI(혹은 워커)에서 수행
FastAPI BackgroundTask
Celery worker
RQ worker
multiprocessing 기반 worker
→ API 이벤트 루프와 계산 이벤트 루프를 절대로 공유하지 않는다.
“같은 사이트/같은 시나리오/같은 연도”에 대해
중복으로 계산 요청(job)이 들어오는 문제.
UNIQUE(site_id, scenario, horizon)
이러면 중복 요청이 들어오면:
기존 job 리턴
or
"이미 계산 중" status만 줘도 됨
API 호출 시 idempotency_key를 받고
같은 키면 같은 job 반환.
LLM/Business 서버는 비동기 계산이 얼마나 걸릴지 모르고,
ModelOps는 계산 중인데, 프론트/Agent는 결과가 필요한 상황.
job_id
status = PENDING | RUNNING | COMPLETED | FAILED
error_message
started_at
finished_at
Agent는 다음 API만 사용:
POST /jobs → job 생성
GET /jobs/{id} → 상태 조회
GET /sites/{id}/results → 결과 조회
Agent는 절대 계산 결과를 ModelOps API에서 직접 받지 않는다.
동기 시스템은 실패하면 API가 500을 그냥 내보내버린다.
하지만 비동기 시스템에서는:
워커가 실패했는지
실패했으면 재시도할 건지
실패 로그가 어딨는지
Agent가 실패를 사용자에게 어떻게 전달할지
관리 포인트가 늘어난다.
1) Job 상태를 FAILED로 기록
2) error_message/log_url 저장
3) Agent는 status를 기준으로 리포트 처리
FAILED면 “이번 분석은 실패했습니다. 나중에 다시 시도하세요.”
COMPLETED면 결과 조회 후 LLM 리포트 생성
A와 B 두 요청이 같은 job에 접근해서 다음과 같은 문제가 생김:
A가 status를 RUNNING으로 변경
B도 거의 동시에 status를 RUNNING으로 변경
→ 중복 계산 발생
→ 결과가 엉킴
1) DB level Lock 사용 (SELECT FOR UPDATE)
2) Job state transition 로직을 원자적으로 설계
3) Unique 제약과 Double-start 방지 로직 강화
10명만 써도 동시에 “후보지 8개”씩 계산하면
ModelOps에 80개 job이 쌓임 → CPU 폭주 → 전체 시스템 지연.
Celery → --concurrency=N
ThreadPool → max_workers 설정
Job을 넣기 전에 검증:
if current_running_jobs > MAX:
return 429 Too Many Requests
사업장 분석 > 후보지 분석
최근 요청 > 오래된 요청
비동기 시스템은 결과를 어디에 저장할 것인지도 난제다.
잘못된 패턴:
결과를 계산 API 리턴으로 주려고 함
→ 비동기와 완전히 충돌
E, V, AAL 결과는 반드시 DB(Site-level)로 저장해야 한다.
site_results
--------------
site_id
scenario
horizon
e_score
v_score
aal_value
risk_index
updated_at
Agent는 항상 DB만 읽는다.
[User]
↓
[AI Agent API]
↓ (트리거)
POST /jobs
↓
[ModelOps API]
↓ (백그라운드/워커)
Compute Worker
↓
[DB]
↑
[AI Agent] ← GET /jobs/{id}, GET /results
API와 계산이 섞임 -> 서버 분리 / 워커 사용
중복 계산 -> Unique key / idempotency
상태 추적 -> Job 테이블 도입
실패 -> FAILED 상태 관리
경쟁 조건 -> Lock 사용
작업 폭주 -> concurrency 제한
결과 저장 위치 ->DB 고정
비동기 작업 시스템은 성능 때문에 도입하지만,
성능보다 더 어려운 상태 관리와 일관성 문제가 새롭게 등장한다.
위의 문제와 해결책을 미리 고려하면
ModelOps–AI Agent–Backend가 섞인 복잡한 시스템에서도
안정적으로 “계산 요청 → 비동기 처리 → 결과 조회 → 보고서 생성”
전체 생산라인을 손대지 않고 확장할 수 있다.