[]
        
(Showing Draft Content)

DocumentServices 구성 및 사용

js-collaboration-otDocumentServices 클래스는 서버 측 OT(Operational Transformation) 기능의 핵심 구성 요소로, 문서 스냅샷과 작업(op)을 저장, 제출, 조회하는 등 전반적인 관리를 담당합니다. 이 문서는 DocumentServices의 생성 및 사용 방법을 다음 항목을 중심으로 설명합니다.

  • 문서 스냅샷 및 작업 저장/조회

  • 작업 제출 및 스냅샷 업데이트 처리

  • 미들웨어 및 훅 확장 추가

사용 사례

  • OT 동작 커스터마이징

  • 성능 최적화

  • 특정 영속성(persistence) 솔루션 구현

초기화

DocumentServices 초기화

생성자 구성

DocumentServices는 생성자에서 설정 객체(IDocConfig)를 전달받아, 데이터베이스 및 동작 관련 파라미터를 커스터마이징할 수 있습니다.

설정 파라미터

파라미터 이름

타입

설명

기본값

db

IDataBaseAdapter

스냅샷과 작업을 저장하는 데이터베이스 어댑터

MemoryDb

milestoneDb

IMilestoneDataBaseAdapter

주기적인 스냅샷 저장에 사용되는 마일스톤 데이터베이스 어댑터

인메모리 구현

maxSubmitRetries

number

작업 제출 시 최대 재시도 횟수

제한 없음

submitSnapshotBatchSize

number

누적된 작업(op)을 현재 스냅샷에 적용한 뒤, 갱신된 스냅샷을 데이터베이스에 제출하기 전까지 허용되는 작업 수

100

submitSnapshotBatchSize에 대한 설명:

이 파라미터는 스냅샷 업데이트 빈도를 정의합니다. 서버에 누적된 작업 수가 이 값에 도달하면, 해당 작업들이 현재 스냅샷에 적용되어 새로운 스냅샷이 생성되고, 기존 스냅샷을 덮어쓰는 형태로 데이터베이스에 저장됩니다.

작업(op) 자체는 별도로 저장되며, 스냅샷은 항상 최신 버전을 유지합니다. 이 메커니즘은 스냅샷 업데이트 빈도와 데이터베이스 쓰기 부하 간의 균형을 맞추기 위한 것입니다.

예제: 기본 설정

import { DocumentServices, MemoryDb } from '@mescius/js-collaboration-ot';

// DocumentServices 설정
const docService = new DocumentServices({
    db: new MemoryDb(),              // 인메모리 데이터베이스 사용
    maxSubmitRetries: 3,             // 최대 3회 재시도
    submitSnapshotBatchSize: 50      // 작업 50개 누적 시 스냅샷 업데이트
});

기본값은 개발 및 테스트에 적합한 MemoryDb입니다.

운영 환경에서는 영속 저장소를 사용하는 어댑터(예: Postgres 어댑터)를 사용하는 것을 권장합니다.

서버 측 작업(Op) 처리 흐름

construct_documentServices.ab15fd.png

메서드

use

작업 처리 과정에 커스텀 로직을 추가하기 위해 미들웨어를 등록합니다.

use<K extends keyof IDocMiddlewareContext<S, T>>(
  action: K,
  middleware: IMiddleware<IDocMiddlewareContext<S, T>[K]>
)

매개변수

  • action: 미들웨어 동작 이름 (예: "submit", "receive")

  • middleware: 미들웨어 함수 (IMiddleware 타입). 컨텍스트를 전달받아 처리 흐름을 제어합니다.

예제

docService.use('submit', async (context, next) => {
    console.log('작업 제출:', context.request.op);
});

on

작업 이벤트를 수신하기 위한 훅(hook)을 등록합니다.

on<K extends keyof IDocHookContext>(
  hookName: K,
  hook: IHook<IDocHookContext[K]>
)

매개변수

  • hookName: 훅 이름 (예: "submitRequestEnd")

  • hook: 훅 함수 (IHook 타입), 컨텍스트를 인자로 받습니다.

예제

docService.on('submitRequestEnd', (context) => {
    console.log('제출 완료:', context);
});

fetch

지정된 문서의 최신 스냅샷을 조회합니다.

fetch(id: string, context?: IContext): Promise<ISnapshot<S>>

매개변수

  • id: 문서 ID (string)

  • context (선택): 작업 컨텍스트

반환값

Promise<ISnapshot<S>> — 최신 스냅샷을 포함하는 Promise


예제

const snapshot = await docService.fetch('doc1');
console.log('최신 스냅샷:', snapshot.data);

getOps

지정된 문서에서 특정 버전 범위(from 포함, to 미포함)의 작업을 조회합니다.

getOps(
  id: string,
  from: number,
  to?: number,
  context?: IContext
): Promise<IOp<T>[]>

매개변수

  • id: 문서 ID (string)

  • from: 시작 버전 번호 (포함)

  • to (선택): 종료 버전 번호 (미포함)

  • context (선택): 작업 컨텍스트

반환값

Promise<IOp<T>[]> — 작업 배열을 포함하는 Promise


예제

const ops = await docService.getOps('doc1', 0, 5);
console.log(ops);

submit

지정된 문서에 작업을 제출합니다.

submit(
  id: string,
  op: IOp<T>,
  context?: IContext
): Promise<IOp<T>[]>

매개변수

  • id: 문서 ID (string)

  • op: 작업 (IOp<T> 타입)

  • context (선택): 작업 컨텍스트

반환값

Promise<IOp<T>[]> — 처리 결과 작업을 포함하는 Promise


예제

docService.submit('doc1', op);

fetchHistorySnapshot

지정된 문서의 과거 스냅샷을 조회합니다.

fetchHistorySnapshot(
  id: string,
  version?: number,
  context?: IContext
): Promise<ISnapshot<S>>

매개변수

  • id: 문서 ID (string)

  • version (선택): 조회할 대상 버전 번호 (생략 시 최신 스냅샷 반환)

  • context (선택): 작업 컨텍스트

반환값

Promise<ISnapshot<S>> — 과거 스냅샷을 포함하는 Promise


예제

const snapshot = await docService.fetchHistorySnapshot('doc1', 2);
console.log('과거 스냅샷:', snapshot.data);