[post_pointcloud_state_change_worker] Retrying 1 times, error: 504 Gateway Timeout
RCA: [post_pointcloud_state_change_worker] Retrying 1 times, error: 504 Gateway Timeout
Overview#
What Happened#
2026-04-30 16:34:19 UTC에 cupixvista-api-worker 서비스의 PostPointcloudStateChangeWorker가 Slack webhook (hooks.slack.com)에 pointcloud 상태 변경 알림을 전송하는 과정에서 504 Gateway Timeout을 수신했다. 단일 발생이며 Sidekiq retry를 통해 34초 후 자동 복구되었다.
Quick Facts#
| Field | Value |
|---|---|
| exception.class | RestClient::GatewayTimeout |
| exception.message | 504 Gateway Timeout |
| top_frame | post_pointcloud_state_change_worker.rb:24 |
| runtime | Ruby (Rails / Sidekiq) |
| env | production, us-west-2 |
Timeline#
- 2026-04-30T16:34:19Z —
PostPointcloudStateChangeWorker가 Slack webhook 호출 시 504 Gateway Timeout 수신, Sidekiq retry 시작 - 2026-04-30T16:34:53Z — Retry 성공, "Processing completed" 메시지 webhook 전송 완료 (hycrofteng-team3, capture 15915)
- 2026-05-01 — Error Sweeper가 클러스터 감지, RCA 수행
Error Log#
[post_pointcloud_state_change_worker] Retrying 1 times, error: 504 Gateway Timeout
Impact#
- Service:
cupixvista-api-worker - 발생 횟수: 1
- 최초 발생: 2026-04-30T16:34:19.289Z
- 최근 발생: 2026-04-30T16:34:19.289Z
실질적 영향 없음. Retry가 34초 후 성공하여 pointcloud 상태 알림은 정상 전달됨. 사용자 대면 기능에는 영향 없음 (Slack 내부 알림 채널만 관련).
Root Cause Summary#
Slack webhook 엔드포인트(hooks.slack.com)의 일시적 504 Gateway Timeout 응답이 원인이다. PostPointcloudStateChangeWorker(line 24)가 RestClient.post로 외부 Slack webhook을 호출하는데, Slack 인프라의 순간적 지연 또는 중간 프록시/CDN 타임아웃으로 504가 반환되었다. 이는 Cupix 내부 코드 결함이 아닌 외부 서비스의 일시적 장애(transient failure)이다.
Technical Analysis#
Code Path#
- Entry point:
app/models/concerns/notifiable/pointcloud.rb:48— pointcloud 상태 변경 시PostPointcloudStateChangeWorker.perform_async(message)호출 - Worker 실행:
app/workers/post_pointcloud_state_change_worker.rb:13—perform(message)메서드 시작 - HTTP 호출:
app/workers/post_pointcloud_state_change_worker.rb:24—RestClient.post SLACK_SERVICE_WEBHOOK_URL, data.to_json - Failure point: line 24에서 Slack이 504 응답 반환
- Retry 로깅:
app/workers/post_pointcloud_state_change_worker.rb:5-7—sidekiq_retry_in콜백에서 에러 로그 출력
class PostPointcloudStateChangeWorker
include Sidekiq::Worker
sidekiq_options queue: :default, retry: 2
sidekiq_retry_in do |count, e|
Cupix::Logger.error("[post_pointcloud_state_change_worker] Retrying #{count + 1} times, error: #{e.message}")
end
sidekiq_retries_exhausted do |job, e|
Cupix.logger.error "[post_pointcloud_state_change_worker] Final retry attempt failed: #{job['args'].first}, error: #{e.message}"
end
def perform(message)
channel = 'pointcloud-state'
channel = "pointcloud-state-#{Rails.env}" unless Rails.env.production?
data = {
channel: channel,
username: $SLACK_REGION_USER_NAME,
icon_emoji: SLACK_REGION_ICON,
text: message
}
RestClient.post SLACK_SERVICE_WEBHOOK_URL, data.to_json, content_type: :json
Cupix::Logger.info("[post_pointcloud_state_change_worker] Successfully sent message to webhook: #{message}")
end
end
기대 동작: RestClient.post가 Slack webhook에 JSON payload를 전송하고 200 OK를 수신한 후 성공 로그를 출력한다.
실제 동작: Slack이 504 Gateway Timeout을 반환하여 RestClient::GatewayTimeout 예외가 발생했고, Sidekiq의 sidekiq_retry_in 콜백이 에러 메시지를 로깅한 후 자동 retry를 수행했다.
주요 특징:
RestClient.post에 명시적 timeout 설정이 없어 기본값(open: 60s, read: 60s) 적용retry: 2설정으로 최대 2회 retry 가능 (총 3회 시도)sidekiq_retry_in콜백이 retry 횟수를error레벨로 로깅하여 error-sweeper에 감지됨
Log Evidence#
사용한 Datadog 쿼리:
service:cupixvista-api-worker status:error @environment:production "post_pointcloud_state_change_worker"
에러 발생 로그 (유일한 에러):
2026-04-30T16:34:19.289Z [error] [post_pointcloud_state_change_worker] Retrying 1 times, error: 504 Gateway Timeout
Retry 성공 로그 (34초 후):
2026-04-30T16:34:53.294Z [info] [post_pointcloud_state_change_worker] Successfully sent message to webhook - Processing completed (hycrofteng-team3, project axfvms, capture 15915)
동일 시간대 다른 성공 전송 로그:
2026-04-30T16:33:25.282Z [info] Successfully sent message to webhook - Processing completed (studiotecnicorodolfo, project ao4u1p, capture 15927)
2026-04-30T16:31:15.265Z [info] Successfully sent message to webhook - Waiting in queue (hycrofteng-team3, project axfvms, capture 15915)
- 에러 전후 다른 webhook 전송은 모두 정상 — Slack의 일시적 장애임을 확인
cupixvista-api서비스에는 동일 시간대 관련 에러 없음 — 하류 서비스 문제 아님
Hypotheses Considered#
| # | Hypothesis | Evidence for | Evidence against | Verdict |
|---|---|---|---|---|
| H1 | Slack webhook 인프라의 일시적 504 (transient failure) | 단일 발생, 34초 후 retry 성공, 전후 동일 worker 성공 로그 존재, cupixvista-api에 관련 에러 없음 |
— | Confirmed |
| H2 | 내부 프록시/ALB 타임아웃 (outbound 요청 차단) | 504는 일반적으로 프록시에서 발생 | 다른 webhook 전송은 동시간대 정상, 네트워크 전반 장애 징후 없음 | Rejected |
| H3 | RestClient 기본 timeout(60s) 초과로 인한 자체 타임아웃 | timeout 미설정 | 에러 메시지가 "504 Gateway Timeout"(HTTP 응답)이며 "execution expired"(Ruby timeout)가 아님 | Rejected |
Fix Recommendation#
즉시 조치 (Critical)#
없음. 단일 발생이며 자동 복구됨. 코드 결함이 아닌 외부 서비스 일시적 장애.
단기 개선 (1주 이내)#
- 로그 레벨 변경:
sidekiq_retry_in콜백(line 5-7)의 로그 레벨을error에서warn으로 변경. 외부 서비스 일시적 장애로 인한 retry는 정상 운영 시나리오이며, retry 실패 시(sidekiq_retries_exhausted)에만error를 유지하는 것이 적절하다. - 명시적 timeout 설정:
RestClient.post에timeout: 10, open_timeout: 5옵션을 추가하여 불필요한 60초 대기를 방지.
장기 개선 (재발 방지)#
- 외부 webhook 호출에 circuit breaker 패턴 적용 검토 (Slack 장애 시 불필요한 retry 및 queue 적체 방지)
- Slack webhook 대신 Slack Web API (
chat.postMessage)로 마이그레이션 시 더 세밀한 에러 핸들링 가능
Monitoring#
sidekiq_retry_in로그를warn으로 변경 후 별도 모니터 불필요- 반복 발생 시 아래 쿼리로 추적:
service:cupixvista-api-worker "post_pointcloud_state_change_worker" "504"
Risk Assessment#
- Risk level: low
- 예상 복잡도: trivial