0002. LiveSyncの同期ってどうして早いの?

さて。早速移転して早速重たそうな話題を持ち込んできました。きみのぶです。
このサイトのタイトルにもなっている同期技術。僕は同期というものに並々ならぬ執着を持っています。これが実に面白いのです。まぁ、だからSelf-hosted LiveSyncみたいなプラグインを作っているのですが。
と言う事で、同期技術の話を書いていきますね。最初にネタ出し尽くしたら後で息切れしそう

同期の種類 #

さて世の中には同期と呼ばれているものがそこそこありますが、そのうち半分ぐらいのものは、実際には比較と上書きしか行っていなかったりします。まぁ同期と言えば同期なのですが…。
ぷーおんさんの所でも散々語りましたが、同期というのは僕の中では、積み上げた歴史をお互いに交換するような行為だと思ってます。なので、比較するまでもなく、前回交換したところから先を持ち寄って、同時にお互い書き込んじゃった所を各自訂正してさらに持ち寄る、そんな感じですね。
ちなみにSelf-hosted LiveSyncが使っているCouchDBやPouchDBはこの通りに動きます。これはCouchDB使ってたら当たり前の実装なので割愛しますね。今回はこの差分同期の中でも、LiveSyncがやってるトラフィック節約について書いてみます。

LiveSyncがやってるエコ #

Self-hosted LiveSyncは、Obsidian上のファイルを一旦Obsidianから勝手に拝借したデータベースに保管しています。その時に、ファイルをメタデータとチャンクというものに分けて保存。チャンクはファイルの内容を都合の良いところで切ったものです。メタデータにはファイル名、変更日、サイズ、そして使用しているチャンクの一覧が保存されています。
だいたいこう言う構造ですね。

graph LR
	A.md-->A;
	B.md-->B;
	C.md-->C;
    A-->1["Willy Wonka, Willy Wonka"];  
    A-->2["The amazing Chocolatier"]; 
    A-->1; 
    A-->3["Everybody give a cheer!"];  
    B-->4["Charlie and the Chocolate Factory"];  
    B-->5[" is a 2005 musical fantasy film"];
    C-->6["When I heard `Wonka's welcome song`, so upset."];
    C-->7["I'm still afraid this."];
    subgraph storage
		A.md
		B.md
		C.md
	end
	subgraph localDatabase
		subgraph metadata
			A
			B
			C
		end
		subgraph chunks
			1
			2
			3
			4
			5
			6
			7
		end
	end
  

このチャンクは、mdファイルの場合は改行やheadingなんかで分割され、その中身のハッシュでIDがつけられます。思いついた時はなかなか冴えてると思いました。
で、送る側はこのメタデータとサーバに存在しないチャンクのみをサーバに送信。なので、ファイルを編集してもメタデータと変更された行のチャンクだけが送信されます。例えば

Willy Wonka, Willy Wonka
The amazing Chocolatier
Willy Wonka, Willy Wonka
Everybody give a cheer!

Willy Wonka, Willy Wonka
The amazing Chocolatier!
Willy Wonka, Willy Wonka
Everybody give a cheer!

にするとメタデータとThe amazing Chocolatier!だけが送信対象。実にエコですよね。
また、サーバにないものだけを送信するのでThe amazing Chocolatier!と何かで書いたことがあれば再利用されます。実にエコ。ためらい変更し放題です。

同期する際にはサーバと歴史を交換することは前述の通りですが、衝突が無い限りは一番最新の状態だけ転送します。つまりその間のリビジョンで発生した、途中経過は転送されません。
受信時には、最近のバージョンで実装されたRead chunks onlineが有効になっているため、最新のメタデータとそれで使用されているチャンクだけが取得されます。結果として必要最低側のデータ転送で修正が転送される事になります。いやはやすごいですね

また、End to Endの暗号化は、転送する際に転送するデータだけにオンメモリで実行されます。安全で、そして最低限。工夫しがいがあった所ですね。

そんなこんなで、ここ数バージョンでSelf-hosted LiveSyncはめちゃくちゃ高速化しました。それが原因で、早くなりすぎてIBM CloudantのAPI制限に当たりやすくなってしまい、多少の修正が必要になったりしたぐらい。
まだIssueも落ち着いていないですが、ここはがっつり直して進めていきたいですね。
早く返事書かないと(英語で返信するには体力が……)

こんな感じで、強めの思い入れで同期プラグイン作ってます。何か疑問点とかあったらぜひ教えてください。

2022/10/16 45分。前後半にすべきだったか。