개발 slecs

광고 슬롯 CDN 레이스 컨디션을 폴링 가드로 해결

목차

비동기 CDN 로드 타이밍 문제로 광고 슬롯 컴포넌트에서 레이스 컨디션이 발생하고 있었다.

배경 — 왜 이게 문제였나

MobonSlot.astro는 외부 광고 SDK(HawkEyes)를 호출하는 컴포넌트다. 문제는 해당 SDK가 CDN을 통해 비동기로 로드되는 방식이라는 것. 컴포넌트가 마운트되는 시점과 CDN에서 스크립트가 실제로 준비되는 시점이 맞지 않으면, HawkEyes 호출 자체가 undefined 참조 에러로 터지거나 무음으로 실패하는 상황이 발생한다.

이런 류의 버그는 로컬에서 재현이 잘 안 된다는 게 특히 까다롭다. 로컬은 캐시가 따뜻하고 네트워크 레이턴시가 없으니까 CDN 스크립트가 거의 항상 먼저 준비돼 있다. 하지만 실제 서비스 환경, 특히 사용자가 콜드 상태로 처음 페이지에 진입하거나 네트워크가 느린 환경에서는 컴포넌트 실행 시점이 CDN 로드보다 앞서는 경우가 충분히 생긴다.

작업 내용 — polling guard 패턴

핵심은 HawkEyes 호출을 그냥 바로 실행하지 않고, SDK가 실제로 준비됐는지를 먼저 확인한 뒤 실행하도록 감싸는 것이다. 흔히 쓰는 패턴이 polling guard인데, 아래처럼 생겼다.

function waitForHawkEyes(callback, interval = 100, timeout = 5000) {
  const start = Date.now();

  const poll = () => {
    if (typeof window.HawkEyes !== 'undefined') {
      callback();
      return;
    }
    if (Date.now() - start > timeout) {
      console.warn('[MobonSlot] HawkEyes load timeout');
      return;
    }
    setTimeout(poll, interval);
  };

  poll();
}

waitForHawkEyes(() => {
  window.HawkEyes.init(/* ... */);
});

typeof 체크로 전역 객체 존재 여부를 확인하고, 없으면 일정 간격으로 재시도한다. timeout을 함께 걸어두는 게 중요한데, 무한 폴링이 되면 안 되니까. SDK 로드가 영구적으로 실패했을 때 graceful하게 빠져나오는 출구를 반드시 만들어둬야 한다.

방식 장점 단점
바로 호출 단순함 레이스 컨디션 발생 가능
DOMContentLoaded / load 이벤트 이벤트 기반, 깔끔 이미 발화된 이벤트는 못 잡음
polling guard 타이밍 무관하게 안전 약간의 딜레이 / 폴링 오버헤드
Promise + custom event 우아한 비동기 흐름 SDK 측 수정 필요 or 래퍼 복잡

외부 CDN 스크립트처럼 우리가 로드 타이밍을 제어할 수 없는 경우, polling guard가 현실적으로 가장 안전한 선택이다. load 이벤트 기반은 이미 이벤트가 발화된 뒤에 리스너를 붙이면 그냥 죽어버리는 엣지케이스가 있어서 외부 SDK에는 맞지 않을 때가 많다.

회고 — 이 작업이 팀에 주는 시사점

변경 파일이 MobonSlot.astro 하나라는 게 핀포인트 수정임을 보여준다. 코드 양 자체는 많지 않지만, 이런 종류의 fix가 사실 팀 관점에서 꽤 중요한 이유가 있다.

  • 광고 슬롯은 수익과 직결되는 컴포넌트다. 무음 실패가 곧 노출 손실
  • 재현이 어려운 버그일수록 "나는 못 보겠는데요" 하고 넘어가기 쉽다. 실제로 이런 버그는 사용자 환경 리포트나 네트워크 조건을 throttle 걸고 테스트해야 드러남
  • Astro 같은 정적/하이브리드 프레임워크에서 <script> 실행 타이밍은 생각보다 예민하다. SSR/SSG 빌드 결과물에서 클라이언트 사이드 스크립트가 언제 실행되는지 팀 전체가 인식을 맞춰두는 게 중요함

코드리뷰 때 외부 SDK 호출이 보이면 "이거 CDN 로드 보장 어떻게 해요?"를 습관적으로 물어보게 된 계기가 됐다. 당연히 돼 있겠지 하고 넘어가기 쉬운 부분인데, 실제로 빠져 있는 경우가 생각보다 많다.


다음엔 Astro에서 외부 스크립트 의존성이 있는 컴포넌트를 어떻게 테스트할 수 있는지 정리해볼 것 같다.


🛒 이 글과 어울리는 추천 상품

*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.

댓글 0

첫 댓글 달아줘.