背景
PC は Microsoft(Outlook/To Do)、モバイルは Google(Tasks/Gmail)。タスクが両方に散らばって二重管理になるのが常態だった。既存の連携サービスはサブスク制か、タスクデータを第三者のサーバーに預けるものばかり。そこで自分で同期エンジンを書いた。実行環境は Google Apps Script、MIT ライセンスの OSS として公開している。
- GitHub: https://github.com/simonchai-tw/tasks-todo-sync
- Website: https://simonchai-tw.github.io/tasks-todo-sync/
設計原則:曖昧な状態では推測しない
同期エンジンで一番怖いのは、「たぶんこうだろう」と推測してデータを壊すことだ。このエンジンは fail-closed を徹底している。壊れたデータより、止まった同期の方がマシ、という判断である。
- 書き込みは fail-closed:両側の状態が曖昧なまま書き込まない。競合は上書きせず、確認待ちとして隔離する。
- 削除は2ラウンドで確定:1回目の同期で削除の証拠を集め、2回目で確定する。誤削除の伝播を防ぐための設計。
- 状態はチェックサム付きで保存:全マッピングにチェックサムを付け、破損したらリストアできる。
- Time Bridge:日付まわりの編集デッドロックを専用レコードで解決する仕組み。
- 繰り返しタスクは所有者側に残す:Microsoft 側で生まれた繰り返しタスクにはエンジンが手を出さず、Google 側に重複コピーを作らない。
Apps Script の制約との戦い
状態は User Properties に gzip+Base64 で圧縮して保存する。ボトルネックはタスク数ではなくバイト数だ。圧縮後のテストでは600ペアまで問題なく、各タスクが極端に重い場合でも300ペアが安全な上限。個人利用には十分な容量で、逼迫時にはメールで通知する。
検証
549 件の自動テストが全パス。さらに状態機械・ファジング・並行性・ミューテーションテスト・静的整合性の五軸で adversarial review をかけ、デッドロックや認証異常時の次回ポーリング詰まりといったバグを潰した。
エンドユーザー向け:Windows ワンクリックインストーラー
ここまでは開発者向けの話。エンドユーザー向けには Windows のワンクリックインストーラーを用意した。セットアップウィザードが案内し、同期パネルで状態と設定を確認できる。ターミナル操作は不要。
セルフホスト
自分の Google Apps Script プロジェクトの中で動くセルフホスト型で、タスクデータが第三者のサーバーを通ることはない。質問・機能要望は GitHub Issues で歓迎する。