Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
pankona opened this issue Sep 30, 2021 · 6 comments
Open

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

pankona opened this issue Sep 30, 2021 · 6 comments

Comments

@pankona
Copy link
Owner

pankona commented Sep 30, 2021

現在

  • 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 pankona changed the title cloud との同期に関するメモ cloud との同期をもう少しいい感じにする Sep 30, 2021
@pankona
Copy link
Owner Author

pankona commented Sep 30, 2021

upload の戦略

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

@pankona
Copy link
Owner Author

pankona commented Oct 11, 2021

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

[問題の動作]

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

[何が問題か]

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

[解決案]

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

@pankona
Copy link
Owner Author

pankona commented Oct 11, 2021

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

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

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

@pankona pankona changed the title cloud との同期をもう少しいい感じにする Cloud との同期をもう少しいい感じにする Oct 11, 2021
@pankona
Copy link
Owner Author

pankona commented Oct 11, 2021

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

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

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

@pankona
Copy link
Owner Author

pankona commented Oct 11, 2021

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

@pankona
Copy link
Owner Author

pankona commented Oct 11, 2021

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant