diff --git a/tools/template/architecture.md b/tools/template/architecture.md index b334901..9268f3d 100644 --- a/tools/template/architecture.md +++ b/tools/template/architecture.md @@ -251,7 +251,7 @@ fn Connection.handleMessage(msg: string){ 디스패치가 성공적으로 이루어지면 RPC 작업를 처리하는 함수에 도착합니다. 청크 작업을 예로 들겠습니다. 청크 작업에서는 권한을 확인하고 -명령의 충돌을 과거를 비교하며 다시 적용하며 해결합니다. +명령의 충돌을 히스토리를 비교하며 다시 적용하며 해결합니다. 그리고 요구된 작업을 처리하고 문서의 `updatedAt`을 업데이트하고 문서 업데이트 사실을 이 문서를 보고 있던 참여자에게 전파합니다. ``` @@ -289,12 +289,52 @@ fn ChunkOperation(conn, m){ 문서 작업도 마찬가지로 이루어집니다. -### 클라이언트의 처리 +### 클라이언트의 메세지 처리 동기화 클라이언트에서는 다음과 같은 일이 일어납니다. +먼저 `notification`을 받습니다. 그러면 모든 `DocumentViewModel`에게 이벤트를 전달합니다. +그리고 각각의 `DocumentViewModel`은 자기 문서에 일어난 일인지 확인하고 `ChunkListMutator`를 만들어서 +문서에 적용합니다. +``` +Input: e RPCNotification +Input: this document view model + +fn updateOnNotification(this,notification){ + { docPath, method, seq, updatedAt } = notification.params; + if (docPath !== this.docPath) return; + mutator = ChunkListMutatorFactory.createFrom(method); + this.apply(mutator, updatedAt, seq); +} ``` +문서의 레디큐에 mutator를 집어넣고 `seq` 번호가 기다리는 것이면 실행하고 업데이트합니다. + +``` +Input: mutator ChunkListMutator +Input: updatedAt Date +Input: seq number +Input: this Document View Model + +//readyQueue is priority queue. +fn apply(this, mutator, updatedAt, seq){ + this.readyQueue.push({mutator, updatedAt, seq}) + + if(this.readyQueue.lenght < some limit){ + while(!readyQueue.empty() && + this.readyQueue.top().seq === this.seq + 1) + { + mutator, updatedAt, seq = this.readyQueue.pop(); + mutator(this.chunks); + this.seq = seq; + this.updatedAt = updatedAt; + } + this.dispatch(new Event("chunksChange")); + } + else { + document.refresh(); + } +} ``` ### 다른 작업들