Api::V1::BimRevisionsController#create_forge_translation_callback (avg 1305ms, max 1305ms)
RCA: BimRevisionsController#create_forge_translation_callback Latency (1305ms)
Overview#
What Happened#
2026-05-26 10:02:54Z에 ap-southeast-2 리전의 cupixworks-api 서비스에서 POST /api/v1/bim_revisions/4873/forge_translation_callback 요청이 1303.7ms 소요되었다. DB 시간은 28ms에 불과하며, 나머지 ~1275ms는 Autodesk Forge API에 대한 두 번의 동기 HTTP 호출(OAuth 토큰 발급 + Webhook 등록)에서 발생했다. 이는 단발성이 아닌 시스템적 패턴으로, 14일간 동일 엔드포인트에서 50건 이상의 1000ms+ 요청이 확인된다.
Quick Facts#
| Field | Value |
|---|---|
| resource_name | Api::V1::BimRevisionsController#create_forge_translation_callback |
| top_frame | app/repositories/bim_revision_repository.rb:14-32 |
| env | production, ap-southeast-2 |
| deploy | production-ap-southeast-2-20260526t0527z0-dd7bd097-cupixworks |
Timeline#
- 2026-05-26T10:02:54Z — POST 요청 수신 (bim_revision 4873)
- 2026-05-26T10:02:55.738Z — 요청 완료 (HTTP 200, 1303.7ms)
- 2026-05-26T10:03:58Z — SalesforceWebToCaseWorker 후속 job 실행
- 2026-05-26T10:09:52Z — 동일 팀의 후속
PUT /api/v1/bims/3458/meta/forge호출
Error Log#
{
"resource_name": "Api::V1::BimRevisionsController#create_forge_translation_callback",
"service": "cupixworks-api",
"occurrences": 1,
"avg_ms": 1305,
"max_ms": 1305,
"sample_trace_id": "2926049172441872771"
}
Impact#
- Service:
cupixworks-api - 발생 횟수: 1 (이번 클러스터), 50+ (14일간 동일 패턴)
- 최초 발생: 2026-05-26T10:02:54.205Z
- 최근 발생: 2026-05-26T10:02:54.205Z
- 영향 범위: BIM 파일 업로드 후 Forge 변환 시작 workflow 전체에 영향. 사용자 대기 시간이 1초 이상 증가하며, 특히 아시아-태평양 리전에서 두드러짐.
Root Cause Summary#
create_forge_translation_callback 요청 경로에서 Autodesk Forge API로의 두 번의 동기 HTTP 호출(OAuth 토큰 발급 + Webhook 등록)이 순차적으로 수행되며, 이것이 전체 1305ms 중 ~1000ms 이상을 차지한다. OAuth 토큰은 매 요청마다 새로 발급받고 있으며(캐싱 없음), Webhook 등록도 동기적으로 처리된다. Autodesk API 서버가 US/EU에 위치하여 아시아-태평양 리전에서는 네트워크 왕복 지연이 추가된다.
Technical Analysis#
Code Path#
- Entry point:
app/controllers/api/v1/bim_revisions_controller.rb:26 - Authentication:
app/controllers/concerns/verification_controller.rb:15— Cognito 인증 (외부 호출) - Permission check:
app/repositories/bim_revision_repository.rb:152-332— 11개 LEFT JOIN 쿼리 - Failure point (latency source):
app/repositories/bim_revision_repository.rb:14-32— 두 번의 동기 외부 HTTP 호출
1단계: OAuth 토큰 발급 (동기 HTTP POST)
def create_forge_translation_callback(params)
# HTTP POST #1: OAuth token request
# autodesk_forge/authentication/v2/token 으로 매 요청마다 새 토큰 발급
# 캐싱 없이 매번 수행됨 — 예상 소요: 200-500ms
end
기대 동작: OAuth 토큰을 캐싱하여 재사용 (TTL 3600초) 실제 동작: 매 요청마다 새 토큰을 동기적으로 발급
2단계: Webhook 등록 (동기 HTTP POST)
# HTTP POST #2: Webhook registration
# autodesk_forge/webhooks/v1/systems/derivative/events/extraction.finished/hooks
# forge_translation_callback_url 내부에서 set_forge_callback_token! 호출 → save!
# set_forge_workflow_id! 호출 → save!
# 응답 201이면 forge_webhook_location save! — 총 3번 DB write
기대 동작: Webhook 등록을 비동기 worker로 처리 실제 동작: 요청 스레드에서 동기적으로 외부 API 호출 후 3번의 개별 save! 수행
3단계: 직렬화 시 S3 호출
# forge_translated_list: S3 list_objects + presign for each object
# bim_revision_result_urls: S3 presigned URLs
# fields 파라미터에 포함된 경우 추가 네트워크 지연
DB save! 3회 분산 호출:
# set_forge_workflow_id! → self.save!(touch: false) [1회]
# set_forge_callback_token! → self.save!(touch: false) [2회]
# forge_webhook_location 저장 → model.save(touch: false) [3회]
# 하나의 save!로 통합 가능
Log Evidence#
검색 쿼리:
service:cupixworks-api @http.url_details.path:"/api/v1/bim_revisions/4873/forge_translation_callback"
핵심 로그 — 요청 완료 로그:
{
"timestamp": "2026-05-26T10:02:55.738Z",
"status": "info",
"http_status": 200,
"method": "POST",
"path": "/api/v1/bim_revisions/4873/forge_translation_callback",
"duration_ms": 1303.7,
"db_ms": 28.06,
"view_ms": 0.12,
"serialization_ms": 0,
"host": "ip-10-1-145-251.ap-southeast-2.compute.internal",
"remote_ip": "54.253.237.17",
"user": "venus.kwok@forida.com.hk (id: 7085)",
"team": "forida-demo (id: 104)",
"user_agent": "cupix-agent"
}
14일간 리전별 latency 패턴:
service:cupixworks-api resource_name:"Api::V1::BimRevisionsController#create_forge_translation_callback" @duration:>1000ms
| Region | Duration Range | DB Time |
|---|---|---|
| ap-southeast-2 | 1155–1710ms | 20–32ms |
| ap-southeast-1 | 1483–1730ms | 23–27ms |
| ap-northeast-1 | 1292ms | 16ms |
| us-west-2 | 1009–1300ms | 13–87ms |
| eu-central-1 | 454–635ms | 21–79ms |
EU 리전이 가장 빠른 것은 Autodesk Forge API 서버가 EU/US에 위치하기 때문이다. 아시아-태평양 리전은 네트워크 왕복 지연으로 인해 일관되게 1100ms+ 소요된다.
후속 Worker 로그:
[SalesforceWebToCaseWorker] start creating new salesforce case. case_type: 'bim_upload_case' sf_resource_id: 'company' model: 'BimRevision' model_id: '4873'
[SalesforceWebToCaseWorker] send web to case successful. case_type: 'bim_upload_case' sf_resource_id: 'company' model: 'BimRevision' model_id: '4873'
Hypotheses Considered#
| # | Hypothesis | Evidence for | Evidence against | Verdict |
|---|---|---|---|---|
| H1 | 동기 Autodesk Forge API 호출(OAuth + Webhook)이 주요 latency 원인 | duration 1303ms 중 DB 28ms뿐 — 1275ms 미확인 시간. 코드에서 두 번의 동기 HTTP POST 확인 (bim_revision_repository.rb:14-32). EU 리전(Forge 서버 근접)에서 454ms로 빠름 |
— | Confirmed |
| H2 | DB 쿼리 성능 문제 (11 LEFT JOIN permission query) | permission_joins에 11개 LEFT JOIN 존재 | DB 시간 28ms로 전체의 2%에 불과. 인덱스 존재 확인 | Rejected |
| H3 | 직렬화 시 S3 호출이 latency 원인 | forge_translated_list에서 S3 list_objects + presign 수행 |
serialization_ms: 0으로 기록됨. params에 해당 필드 미포함 (fields: ["id","name","bim","bim_comparison_state","forge_urn","forge_format_type","forge_region","forge_workflow_id","meta"]) |
Rejected |
| H4 | 서버 부하로 인한 일시적 지연 | — | 동일 호스트의 다른 요청은 30-150ms로 정상. 14일간 동일 패턴 반복 | Rejected |
Fix Recommendation#
즉시 조치 (Critical)#
app/repositories/bim_revision_repository.rb:14-19— Autodesk OAuth 토큰 캐싱 추가. 토큰 TTL이 3600초이므로 Rails.cache에expires_in: 50.minutes로 캐싱하면 요청당 ~200-500ms 절감.app/models/concerns/forge_translatable/properties.rb:29-61— 3회의 개별save!호출을 1회로 통합.forge_workflow_id,forge_callback_token,forge_webhook_location을 한 번에 assign 후 단일 save! 수행.
단기 개선 (1주 이내)#
- Webhook 등록(
bim_revision_repository.rb:23-32)을 비동기 Sidekiq worker로 이동. 이미FinishBimRevisionForgeTranslationWorker가 비동기 패턴을 사용하고 있으므로 동일 패턴 적용. - 응답에서 webhook 등록 결과가 불필요하다면, 요청 스레드는 DB 작업만 수행하고 외부 API 호출은 worker에서 처리.
장기 개선 (재발 방지)#
- Autodesk Forge API 호출을 전담하는 service object 분리. OAuth 토큰 관리, 재시도 로직, 타임아웃 설정을 중앙화.
- ap-southeast-2 리전 전용 Forge API proxy나 리전별 캐시 레이어 도입 검토. 현재 아시아-태평양 리전에서 일관되게 1100ms+ 소요되는 패턴을 해소.
Monitoring#
- Forge API 호출 latency를 별도 custom metric으로 추적:
service:cupixworks-api @http.url:*autodesk* | measure by @duration
forge_translation_callbackP95 latency 알림 (threshold: 1000ms):
avg(last_5m):trace.rack.request{service:cupixworks-api, resource_name:Api::V1::BimRevisionsController#create_forge_translation_callback} > 1000
- OAuth 토큰 캐시 hit/miss rate 모니터링 추가
Risk Assessment#
- Risk level: low (기능 정상 동작, 사용자 대기 시간만 증가)
- 예상 복잡도: standard (OAuth 캐싱은 trivial, Webhook 비동기화는 기존 worker 패턴 참조 가능)