채널톡이 Redux를 걷어내고 RxJS와 Zustand로 대규모 SDK 비동기 흐름을 정복한 여정
예측 불가능한 SDK 실행 타이밍에서 발생하는 프론트엔드 비동기 버그를 극복하기 위해, 채널톡이 아키텍처를 전면 개편한 생생한 트랜지션 스토리입니다. 복잡한 소켓 이벤트 체인을 RxJS 스트림으로 직렬화하고 Zustand로 실시간 동기 처리를 결합해, 비결정적이었던 시스템 타이밍을 구조적으로 완벽히 정복한 인사이트를 소개합니다.
예측 불가능한 유저 행동이나 다수의 연쇄적 비동기 인터페이스 처리가 필요해 타이밍 디버깅에 큰 어려움을 겪고 있는 대규모 웹 애플리케이션 및 라이브러리 빌더 조직에 추천합니다.
채널톡 SDK에서 인터페이스(boot, shutdown)가 실행될 때, 네트워크 응답만을 기준으로 완료를 판단하면서 이후 발생하는 소켓 연결 등의 비동기 사이드 이펙트들이 통제되지 않고 다음 작업과 병렬로 얽히는 버그가 발생했습니다. 또한 비즈니스 로직이 컴포넌트, 미들웨어, 에픽 등 코드 곳곳에 파편화되어 비동기 흐름의 끝맺음을 제어하기 어려운 구조였습니다.
비동기 흐름을 통제하기 위해 RxJS를 도입하여 비즈니스 로직을 선언적인 스트림 파이프라인으로 재조합하고 명확한 완료(complete)와 취소 시점을 정의했습니다. 이와 동시에, 흐름 중간에 즉시 상태 업데이트를 동기적으로 반영할 수 있도록 Zustand 상태 관리 라이브러리를 결합하였으며, 컴포넌트는 UI 렌더링과 이벤트 전송만 전담하는 단순한 구조로 디자인 패턴을 단순화했습니다.
새로운 비즈니스 로직을 작성할 때 작성해야 하는 보일러플레이트 코드가 Redux 사용 대비 절반 수준으로 줄었으며, 소켓 연결 및 이벤트가 타이밍 이슈로 누락되던 문제가 구조적으로 완전히 해결되었습니다. 또한 스트림이 완전하게 종료되거나 구독이 확실히 해제되는 설계가 정착되면서, 장시간 페이지를 구동해두어도 잔여 구독 참조에 따른 메모리 누수가 발생하지 않고 안정적인 성능을 유지할 수 있게 되었습니다.
Trade-off
RxJS 도입으로 비동기 스트림 처리 수준은 고도화되었으나, 팀 내부적으로 복잡한 RxJS 스트림 연산자들을 능숙하게 디버깅하고 다루기 위한 높은 수준의 러닝 커브를 감수해야 하며, 모든 스트림 라이프사이클과 가비지 컬렉션을 설계 단계부터 엄격히 인지해야 하는 예방적 유지 관리 비용이 상존합니다.
시간의 흐름에 따라 비동기적으로 발생하는 데이터 흐름을 스트림으로 모델링하고 조작하는 반응형 프로그래밍 라이브러리입니다.
단순하고 유연한 API를 지원하며, 상태 변경 요청 시 비동기 큐 없이 즉시 동기적인 상태 변경을 적용해주는 React 상태 관리 라이브러리입니다.
비동기 이벤트 스트림들이 중간에 유실되거나 순서가 꼬이지 않도록 직렬화 큐를 두거나, 이전 비동기 동작이 완료될 때까지 이후 이벤트를 완벽하게 대기 상태로 정렬하는 제어 패턴입니다.