GitLab EventStore
GitLab EventStore의 개념, 이벤트 정의·발행·구독 방법, 테스트 방법, 그리고 모범 사례를 설명합니다.
배경 # GitLab 모노리스 프로젝트는 점점 커지고 있으며, 더 많은 도메인이 정의되고 있습니다. 그 결과, 이러한 도메인들은 시간적 결합(temporal coupling)으로 인해 서로 얽히게 됩니다. 대표적인 예로 PostReceive 워커가 있습니다. 이 워커에서는 여러 도메인에 걸쳐 많은 작업이 이루어집니다. 새 커밋 푸시에 반응하는 새로운 동작이 필요하면, PostReceive 또는 하위 컴포넌트(예: Git::ProcessRefChangesService )에 코드를 추가하게 됩니다. 이러한 아키텍처는: 단일 책임 원칙(Single Responsibility Principle)을 위반합니다. 익숙하지 않은 코드베이스에 코드를 추가하는 위험을 증가시킵니다. 알지 못하는 미묘한 부분이 있을 수 있으며, 이로 인해 버그나 성능 저하가 발생할 수 있습니다. 도메인 경계를 위반합니다. 특정 네임스페이스(예: Git:: ) 내부에서 다른 도메인의 클래스( Ci:: 또는 MergeRequests:: )가 불쑥 등장합니다. EventStore란? # Gitlab::EventStore 는 기존의 Sidekiq 워커와 현재의 옵저버빌리티(observability) 위에 구축된 기본적인 pub-sub 시스템입니다. 이 시스템을 사용하여 도메인을 모델링할 때 이벤트 기반 접근 방식을 적용하면서 결합도를 최소화합니다. 이 방식은 기존 Sidekiq 워커를 그대로 유지하면서 비동기 작업을 수행하지만, 의존성의 방향을 역전시킵니다. EventStore 예시 # CI 파이프라인이 생성될 때, 파이프라인의 ref 와 일치하는 모든 머지 리퀘스트의 헤드 파이프라인을 업데이트합니다. 그러면 머지 리퀘스트에서 최신 파이프라인의 상태를 표시할 수 있습니다. EventStore 없이 # Ci::CreatePipelineService 를 변경하고 파이프라인이 생성되었는지 확인하는 로직(예: if 문)을 추가합니다. 그런 다음, MergeRequests:: 도메인의 사이드 이펙트를 실행할 워커를 예약합니다. 이 방식은 개방-폐쇄 원칙(Open-Closed Principle) 을 위반하며 다른 도메인의 사이드 이펙트 로직을 불필요하게 추가하여 결합도를 높입니다: graph LR subgraph ci[CI] cp[CreatePipelineService] end subgraph mr[MergeRequests] upw[UpdateHeadPipelineWorker] end subgraph no[Namespaces::Onboarding] pow[PipelinesOnboardedWorker] end cp -- perform_async --> upw cp -- perform_async --> pow EventStore 사용 시 # Ci::CreatePipelineService 는 Ci::PipelineCreatedEvent 이벤트를 발행하고, 역할이 여기서 끝납니다. MergeRequests:: 도메인은 워커 MergeRequests::UpdateHeadPipelineWorker 로