pile·
프론트엔드·channel-talk채널톡·

RxJS로 우아하게 사이드 이펙트 통제하기

채널톡 고객용 SDK에서 boot→shutdown→boot 연속 호출 시 사이드 이펙트가 중첩되는 타이밍 버그를 RxJS 기반 구조 개편으로 해결한 사례다. 비동기 흐름 직렬화에 RxJS, 동기적 상태 관리에 Zustand를 도입해 타이밍 비결정성을 구조 수준에서 제거했다.

핵심 포인트
  • boot→shutdown→boot 연속 호출 시 선행 사이드 이펙트 완료 전 다음 액션이 실행되는 타이밍 비결정성이 핵심 버그였다.
  • RxJS의 concatMap/switchMap 등 연산자로 비동기 체인을 직렬화해 호출 순서를 구조적으로 보장했다.
  • Redux를 Zustand로 교체해 RxJS pipe 흐름 중간에 action dispatch 없이 동기적 상태 변경이 가능해졌다.
  • "뷰는 뷰만이 할 수 있는 일을 한다" 원칙으로 컴포넌트-비즈니스 로직 책임을 명확히 분리했다.
  • 리팩토링 결과 작성 코드 절반 감소, 삭제 코드가 신규 코드의 2배, 소켓 타이밍 버그 해결, 메모리 누수 방지.
상세 정리
  • 버그 발생: 고객사가 boot→shutdown→boot를 연달아 호출할 때 소켓 연결 같은 후속 사이드 이펙트가 진행 중인 상태에서 다음 작업이 실행되어 소켓 요청 실패.
  • 구조적 원인 분석: SDK는 고객사 호출 순서 통제 불가, 각 액션이 단발성이 아닌 비동기 체인, 전역 상태 공유로 타이밍에 따라 결과가 달라지는 세 가지 구조적 문제.
  • 표면 방어 코드의 한계: 비동기 체인 완료 시점을 알 수 없고 로직이 코드 곳곳에 파편화되어 임시방편으로는 해결 불가.
  • RxJS 선택 근거: redux-observable로 팀 내 이미 익숙, 코드 순서 그대로 흐름 표현 가능, 풍부한 비동기 연산자, 지연 평가로 성능·메모리 효율 확보.
  • 핵심 설계 변경: boot 흐름을 하나의 RxJS pipe로 통합해 "boot 호출 시 무슨 일이 일어나는가"의 답이 한 곳에 집중.
  • Redux 한계와 Zustand 전환: Redux는 비즈니스 로직 실행 중 상태 변경 시 action dispatch 필요로 흐름이 끊기는 반면, Zustand의 store.set()은 동기적 즉시 업데이트가 가능.
  • 책임 분리 흐름: 사용자 이벤트→뷰가 action 호출→RxJS pipe에서 비즈니스 로직 순차 실행→Zustand 동기 상태 업데이트→Selector로 컴포넌트 리렌더링.
  • 구조적 해결: 각 인터페이스 호출이 스트림으로 직렬화되어 이전 호출 사이드 이펙트 완료 후 실행, shutdown이 실행 중인 스트림 구독 해제 담당.
  • 실측 성과: 소켓 연결 전 채팅방 입장 시 join 이벤트 유실 해결, 소켓 단절 중 타이핑 이벤트 유실 해결, 페이지 장시간 사용 시 성능 유지(메모리 누수 방지).
  • 코드량 절감: 작성 코드 절반 감소, 삭제 코드가 신규 코드의 2배 수준으로 구조 단순화.
왜 읽나RxJS로 SDK나 복잡한 비동기 흐름을 구조화하려는 프론트엔드 개발자에게 실전 타이밍 버그 해결 과정과 Redux→Zustand 전환 근거를 제공한다.
channel-talk
채널톡 블로그
원문은 여기서 이어서 읽을 수 있어요
원문 읽기
읽음 (0)

이 글과 비슷한

  1. 프론트엔드·여기어때 (GC컴퍼니)여기어때 (GC컴퍼니)·

    항공 프론트엔드 구축기 (7/10): 창구를 하나만 두었습니다

    여기어때 항공 서비스 프론트엔드가 웹과 앱 웹뷰 두 환경에서 동일한 함수 호출로 동작하는 앱 브릿지 추상화 레이어를 설계한 과정을 다룬다. iOS·안드로이드 규약 차이와 "웹에 존재하지 않는 브릿지를 어떻게 호출하나"라는 문제를 단일 추상화 층으로 해결한 구현 사례다.

    요약 이어보기
    #react#typescript#webview+2
  2. 프론트엔드·토스 SLASH토스 SLASH·

    모노리포 희망편, 절망의 리포가 희망의 리포로 부활하기까지 걸린 1년

    토스 프론트엔드 팀이 100명 이상의 개발자가 사용하는 모노리포에서 겪은 의존성 버전 불일치, 개발 환경 편차, 느린 설치 속도 문제를 pnpm Catalog 도입으로 해결한 1년간의 여정을 다룬다. 카탈로그로 라이브러리 버전을 중앙화한 결과 의존성 설치 시간을 52% 단축하고 .pnp.cjs 파일 크기를 84% 줄이는 데 성공했다.

    요약 이어보기
    #react#pnpm#monorepo+1