hashira icon indicating copy to clipboard operation
hashira copied to clipboard

Cloud との同期をもう少しいい感じにする

Open pankona opened this issue 3 years ago • 6 comments

現在

  • upload ... local の状態を cloud にそのまま反映する
  • download ... cloud の状態を local にマージする

という処理を行っている。これの問題点は、

  • 環境 A と環境 B で異なる変更を行った上で各々が upload を実施した場合、どちらかの変更が失われる
    • 先に download してから upload するという案もあるが、その場合手元で行った変更が失われる場合がある

なので、なるべく

  • 手元の変更を失わずに、
  • よそで発生した変更も失わないように local に反映する

というようにしたい。

以下の手順で同期する

  • local から cloud に upload する
    • cloud は upload されたデータとすでに保存されているデータをマージする (upload されてきたものの状態を優先する)
    • isDeleted フラグがついているものは削除する (物理削除)
  • upload 完了後、local は cloud からデータをダウンロードする
    • local のデータにマージする (download したものの状態を優先する)
    • isDeleted フラグがついているものは削除する (物理削除)

留意する点

  • 物理削除について
    • cloud だけにデータが残ってしまう可能性はないか?
      • local ではすでに消えたデータが、cloud 上ではまだ残っているという状態になる可能性がある
      • ただ、このケースは download 時に復活して見えるはずなので、ふたたび消すというオペレーションをすることでいつかデータの整合性が取れるはず
    • 物理削除する必要があるか?
      • 延々とデータが増え続けてしまうと同期にどんどん時間がかかるようになってしまうので、なるべく残しておきたくない
  • upload & download について
    • いつ実行する?
      • 理想的には、todo に変化が発生したタイミングで常に実行する
      • ネットワークが不通になる状況を考慮する必要があるので、ポーリングする必要もありそう
        • isDirty フラグを使うと、一応不要な通信は抑えられるかもしれない
  • 常に upload を先にやる必要がありそう
    • download を先にやると、手元の変更が失われる場合があるため
    • どっかの環境とコンフリクトするような場合はまあまあやむなし

pankona avatar Sep 30 '21 04:09 pankona

upload の戦略

  • isDirty がついているもののみを upload の対象にする
    • よそで発生した変更を無駄に上書きするのを避けるため
    • 帯域を温存する
  • 一度も sync したことのない場合、全部の task が isDirty: false だが upload が済んでいないという状態になる
    • 初回限定で、一回全部の task を upload する必要がある
    • 一度やってしまえばあとは Dirty フラグのついたものだけ upload する & 全部 download して local に反映する、というロジックでまあまあ整合性が保たれるはず
    • 専用コマンドを用意しとこう

pankona avatar Sep 30 '21 07:09 pankona

いったん実装できたが、以下の問題があることがわかった。

[問題の動作]

  • タスクの追加や並びの変更があったときに、Dirty フラグのついたタスクのアップロードと、全件ダウンロードを行っている

[何が問題か]

  • 手元で素早く複数回タスクを動かすと、アップロードを開始してダウンロードが済む前にいくらか Dirty なタスクが発生することになる
  • アップロードとダウンロードの間で動かしたタスクは、ダウンロードによって状態が上書きされてしまうことがある

[解決案]

  • タスクを動かしたときにただちにダウンロードまでやるのを止める
    • Dirty 発生時はアップロードだけやっとく
    • ほとぼりが冷めた頃合いを見計らってダウンロードを行う (最後にタスクを動かしてから数分後、みたいな)
  • Dirty なタスクはダウンロード時に上書きしない
    • これのほうが安全かも
    • こっちで実装してみる

pankona avatar Oct 11 '21 02:10 pankona

結局以下を両方実装した。

  • ほとぼりが冷めた頃合いを見計らってアップロード/ダウンロードを行う
  • Dirty なタスクはダウンロード時に上書きしない

なんとなくちゃんと動くようになったような気がする

pankona avatar Oct 11 '21 06:10 pankona

ポーリングの機能は実装しなかったのだが、

  • よそで変更する
  • ほっといたら自分のところに同期されている

みたいなのは出来てもよさそうなので、やっぱり定期的にポーリングして UI に反映するのはやったほうが体験がよさそうかもしれない。

pankona avatar Oct 11 '21 08:10 pankona

ダウンロードが完了したら UI をちゃんとリフレッシュするのができてない気がするのでそれは直そう。

pankona avatar Oct 11 '21 08:10 pankona

削除したタスクに関しては同期がとれない (消えてなくなるので、元からなかったのか消したのかの判別ができない)。 これはもう諦める。

pankona avatar Oct 11 '21 08:10 pankona