Cache vs. Sync (Is a False Conflict)

むかし、スマホアプリのオフラインデータモデルは Cache based (サーバが source of truth でクライアントはそれを部分的に cache すると考える) がよいのか Sync based (データはそれぞれがもっていてオンラインの時に同期する) がよいのかとぼんやり考えていた時期があった。

が、いまおもうと空想上の問題だったね。このとき考えていた素朴な答えのひとつは「アプリによる」だったけれど、どちらかというと「どちらも使う」という方が正しいと思う。

オフライン対応のための sync というのは強力なアイデアだけれども、データモデルによっては正しく実装するのが割と難しい。ファイルシステムみたいにネストしたデータ構造 (tree) もけっこう難しいし、一部の TODO アプリみたいな ordered list には別の難しさがある。"最強の sync framework" みたいのを開発し、その上にアプリを作ろうとして失敗するのを遠目に見たことがある。最強のフレームワークが想定するデータモデルの複雑さは大抵のアプリにとって過剰すぎたのだろう。Chrome の profile data sync も、最初はすごい汎用的なフレームワークから始まったものの機能開発者が誰も使いこなせず簡単なモデルに回帰していった。というのは 5 年くらい前の話で、今はどうなってるのかわからんけれど。

その点 cache は比較的簡単。サーバが source of truth だとオフラインでデータを書き換える操作はできないけれど、それでいいものは沢山ある。たとえば shopping アプリなら top selling item list とかは cache でいい。Twitter の timeline みたいのも一見すると自分が参加できるから sync と考えたくなるけれど、投稿された timeline の cache + 投稿前 draft の sync (あるいはクライアントに閉じたコピー)  ともみなせる。Immutable objects + Pending operations として表現すればよい、とも言える。

Twitter みたいな social media は本質的にオンラインなので sync の出番がないのは自然。もうちょっとクライアント中心のアプリだと sync したいものが色々でてくる。けれど、その色々 sync したいものをひとつのデータモデルとして sync しようとするとふたたびデータモデルの複雑さあらわれる。個々の機能がそれぞれ勝手に自分のデータを sync する方が、データ種別毎の単純さをあてにできてよい気がする。ぱっと見ると同じようなコードがあちこちに現れて無駄っぽいし、サーバとの API も工夫しないと round trip が増えてしまうけれど。そこは小細工でがんばる。

なので immutable とみなせるものは cache で済ませ、それ以外はぼちぼち sync する, くらいが現実的には安全。

Sync はなんとなくかっこいい。Offline でも online でも同じように操作ができ、データが透過的にクラウドに保存される。理想的じゃん?でもユーザが offline/online の透過性を求めていないこともよくある。同期の有無やタイミングをコントロールしたいユーザは多い。そしてこの flexibility を許すと透過的な sync という夢は終わる。一方で product design として automagical な sync を実現したい、という意見はあるだろうし、それが望ましいアプリも多いだろう。だから Sync か Cache かは engineering だけでなく product の design でもある。そして答えはアプリ単位でなく機能単位で変わる。だからどちらも必要。

というのは今になってみると当たり前だけれど、何年か前の自分はわかってなかった気がする。そして数年後にはまた気が変わり「やはり最強の sync framework があればいい」とか言ってるかもしれない。