협업 텍스트 편집: CRDT나 OT 없이 구현하기

1 day ago 1

  • 협업 텍스트 편집 문제를 해결하는 새로운 접근법 소개, 복잡한 알고리듬 없이도 실현 가능함
  • 기존 CRDT 및 OT 방식의 복잡성과 제약을 피하고, 간단한 ID 기반 삽입 방식 사용
  • 이 방식은 서버가 '무엇을 어디에 삽입할지'를 직접 지정받아 처리하므로 유연성이 높음
  • 낙관적 로컬 업데이트를 위해 서버 리컨실리에이션 전략을 활용해 상태 동기화 문제 해결
  • 확장성과 이해 용이성을 갖춘 이 방식은 기존 협업 앱 개발에 직접 구현 가능한 대안을 제시함

Collaborative Text Editing without CRDTs or OT

문제 제기

  • 텍스트 협업 편집은 매우 어려운 기능으로, 특히 동시 편집 시 텍스트 인덱스가 뒤틀리는 문제(index rebasing) 가 발생함
  • 기존 방식인 CRDT(충돌 없는 복제 데이터 타입)OT(운영 변환) 는 각각 복잡한 수학적 모델에 기반함
    • CRDT: 각 문자를 ID로 추적하고 트리 기반 정렬
    • OT: 다른 사용자 입력을 반영해 인덱스를 동적으로 재조정
  • 두 방식 모두 라이브러리 의존성이 높고 개발자 맞춤형 커스터마이징이 어려움

새로운 접근 방식

핵심 아이디어

  • 각 문자를 고유한 ID(UUID)로 표시하고, 클라이언트는 서버에 “어떤 ID 뒤에 어떤 문자를 삽입하라”는 명령을 보냄
  • 예: "insert ' the' after f1bdb70a" → f1bdb70a는 삽입 대상 문자 ID
  • 서버는 이를 그대로 해석하여 삽입함으로써 충돌을 회피함

삭제 처리

  • 문자 삭제 시에도 해당 ID는 내부 목록에 남겨 두고 isDeleted 플래그로 처리
  • 실 사용자 텍스트에선 보이지 않지만 참조는 유지되어 향후 조작이 가능

클라이언트 처리와 낙관적 업데이트

  • 사용자는 입력 직후 결과를 볼 수 있어야 하므로, 서버 응답 전 로컬에 반영 (낙관적 업데이트)
  • 서버 리컨실리에이션 전략을 사용하여:
    1. 로컬 미확정 연산을 모두 되돌림
    2. 서버 연산을 적용
    3. 다시 로컬 연산을 재적용하여 최종 동기화 상태 확보

기존 방식과의 차이

  • CRDT는 자동 ID 정렬 알고리듬을 내포하나, 본 방식은 명시적 삽입 위치만 서버에 전달
  • 결과적으로 더 단순하고 명확한 동작 방식 확보

동시 삽입 처리

  • 예: “My name is”에서 두 사용자가 동시에 “ Charlie”와 “ Dave”를 같은 위치에 삽입
    • 서버 수신 순서에 따라 “My name is Dave Charlie”가 됨
  • 이는 자연스러운 처리로 간주되며, 일부 CRDT 방식처럼 문자 단위로 섞이는(interleaving) 현상 없음

유연한 연산 지원

  • 기본적인 insert/delete 외에도 다양한 연산 지원 가능:
    • insert-before
    • 특정 조건 하 삽입 (“color”가 존재할 경우만 “u” 추가)
    • drag & drop 시 위치 재조정 등
  • 이러한 유연성은 정해진 수학적 특성에 얽매이지 않음

리치 텍스트(서식 있는 텍스트) 지원

  • 범위를 ID 기반으로 정의하여 서식 적용 가능 (“ID X부터 ID Y까지 bold” 등)
  • ProseMirror 같은 에디터와 연동 시 간단한 방식으로 충돌 해결 가능
  • 기본 구조는 그대로 유지하면서 리치 텍스트 기능 추가 가능

분산 버전 (Decentralized)

  • 중앙 서버 없이도 Lamport 타임스탬프 기반으로 연산 순서를 정하면 동일 방식으로 작동 가능
  • 이 경우 RGA, Peritext, Fugue 등의 CRDT와 유사한 결과를 보임
  • 트리나 수학적 증명 없이도 CRDT 수준의 일관성 확보 가능

보조 라이브러리: Articulated

  • Array<{ id, isDeleted }> 형태를 효율적으로 다루기 위한 라이브러리
  • UUID 대신 { bunchId, counter } 구조 사용하여 메모리 최적화
  • B+Tree 기반 구조로 빠른 ID 탐색 및 삽입 지원
  • 지속 가능한(persistent) 데이터 구조로 서버 리컨실리에이션과 궁합이 좋음

결론

  • 이 방식은 CRDT/OT에 비해 이해하기 쉽고 직접 구현이 가능
  • 다양한 편집 기능과 권한, 제약, 서식 등을 자유롭게 적용할 수 있어 현실적인 협업 에디터 구현에 유리
  • Articulated 라이브러리는 이러한 접근을 실용화하는 데 도움이 되는 도구로 제공됨

Read Entire Article