harukawa / DriveText

0 stars 2 forks source link

通信をSyncにする #35

Open harukawa opened 4 years ago

harukawa commented 4 years ago

sqliteで通信用のデータベースを新しく作成する。 Syncはserviceで作成する。

harukawa commented 4 years ago

タイムスタンプの取得タイミング

通信をSyncにするにあたって、タイムスタンプの取得についても変更を行う。 ローカルとDriveのファイルのタイムスタンプを保持するのには変更なし

  ローカルのタイムスタンプを更新

  Driveファイルのタイムスタンプを取得。   上記のタイムスタンプで、ローカルとDriveのタイムスタンプを更新

  Driveファイルのタイムスタンプを取得。   上記のタイムスタンプで、ローカルとDriveのタイムスタンプを更新  

  Driveファイルのタイムスタンプを取得。   上記のタイムスタンプで、ローカルとDriveのタイムスタンプを更新

  Driveファイルのタイムスタンプを取得。   上記のタイムスタンプで、ローカルとDriveのタイムスタンプを更新

harukawa commented 4 years ago

メタ情報の取得パターン

1.特定のDriveドキュメント内のファイル一覧情報を取得   2.特定のDriveファイル情報を取得

通信パターン(テキストエディタ)

・アップロード

 1.ファイルをアップロード  2.メタ情報(アップロードファイル)を取得  3.メタ情報からidとタイムスタンプを登録

・アップデート(手動)

 1.ファイルをアップデート  2.メタ情報(アップデートファイル)を取得  3.メタ情報からタイムスタンプを登録

通信パターン(同期)

 1.メタ情報(ファイル一覧情報)を取得  2.メタ情報から処理を決定

・アップデート(ローカル->Drive)

  3.Driveファイルをアップデート   4.メタ情報(アップデートファイル)を取得   5.4で取得したメタ情報のタイムスタンプを登録

・アップデート(Drive->ローカル)

  3.Driveファイルをダウンロードして、ローカルファイルに上書き   4. 1で取得したメタ情報のタイムスタンプを登録

・ダウンロード

   3.ファイルをダウンロード    4. 1で取得したメタ情報を登録

・削除(Driveにアップロードしたファイルがない場合)

   3.ファイルを削除

harukawa commented 4 years ago

ファイル同期時のパターン

  同期で影響を受けるのはアップロードを行ったローカルファイルのみで、未アップロードのidがないファイルには何も行わない 通信で取得したメタ情報から処理を選択する。

ローカルとDriveに同じファイルが存在している場合、ローカルのDBに保存されているタイムスタンプと、通信で取得したメタ情報のタイムスタンプから処理を選択する。

同期時のタイムスタンプの前後関係による処理

タイムスタンプが新しいファイルのほうを残します。

タイムスタンプ種類

処理ケース

・ローカル = Drive = ローカルに保存されているDrive   処理なし 

・ローカル = Drive > ローカルに保存されているDrive   処理なし 

・ローカル >Drive >= ローカルに保存されているDrive   アップデート(ローカル->Drive)

・Drive > ローカル >= ローカルに保存されているDrive   アップデート(Drive->ローカル)

karino2 commented 4 years ago

ローカル >Drive >= ローカルに保存されているDrive   アップデート(ローカル->Drive)

・Drive > ローカル >= ローカルに保存されているDrive   アップデート(Drive->ローカル)

このケースはコンフリクトなので、上書きしちゃまずい事もあると思います。 特に Drive>ローカル>ローカルのD の時にDriveのファイルで上書きすると、ローカルで行った変更はこの世から消えてしまう訳ですよね? それはなにか救済策が欲しい。

karino2 commented 4 years ago

あとローカル、Drive、ローカルに保存されてるDriveのタイムスタンプに、略称を決められないですかね。読みにくいので。 locf, remd, locdとか、l_file, r_drive, l_driveとか。

karino2 commented 4 years ago

救済策は実装が簡単でわかりやすいのが良いですね。 ここはちょっと考えたい所。

karino2 commented 4 years ago

あと手動でアップデートする時に、ドライブ側が更新されてる場合はどうなるのでしょう? 感覚的にはエディタからの送信と同期はだいたい同じコンフリクトのパターンなので、統合した処理になると予想しているのですが。

harukawa commented 4 years ago

コンフリクト

コンフリクトが起きた時は両方の内容を保存したいので、ローカルとドライブのテキストを一つにしたファイルにして保存しようと思います。

ローカルとドライブを見分けるためにセルを追加して、その下のセルにそれぞれのテキスト内容のセルを書き込む感じにしようと考えています。


local-2020-02-03-101010


localのテキストのセル


drive-2020-02-04-110133


driveのテキストのセル


harukawa commented 4 years ago

同期時のタイムスタンプの前後関係による処理

タイムスタンプが新しい変更があったファイルのほうを残します。 両方に変更があった場合は衝突するので、両方の内容をファイルに残します。

タイムスタンプ種類

略称を付けました。

l_file:ローカルファイルのタイムスタンプ(ローカルDB)

r_drive:Driveファイルのタイムスタンプ(メタ情報)

l_drive:ローカルに保存されているDriveファイルのタイムスタンプ(ローカルDB)

処理ケース

・l_file = r_drive = l_drive   処理なし 

・l_file = r_drive > l_drive   コンフリクト   両方のファイルのテキストをまとめて、ローカルとドライブの両方に保存

・l_file >r_drive = l_drive   アップデート(ローカル->Drive)

・r_drive > l_file = l_drive   アップデート(Drive->ローカル)

・l_file >r_drive > l_drive   コンフリクト   両方のファイルのテキストをまとめて、ローカルとドライブの両方に保存

・r_drive > l_file > l_drive   コンフリクト   両方のファイルのテキストをまとめて、ローカルとドライブの両方に保存

karino2 commented 4 years ago

l_file = r_drive > l_drive
このケースはコンフリクトでは。

あと削除のケースもついでに考えたですね。 削除されるとエントリが無くなる、とする(たぶんあってるかな)。 数字が大きい方が新しくて削除をdで表すと

くらいかしら?

karino2 commented 4 years ago

削除をどうするかとコンフリクトをどうするかはちょっと考えたい所でもある。

削除に関して。Drive側はTrashに移す、でいい気もするが、ローカル側がundo出来ないのでちょっと怖い。 理想的にはRecycleBin的なフォルダに移しておいて、いざとなったら手動で復旧出来るのが望ましいけれど、これをどこに置くかとどう復旧するかが悩ましい。 こういう特殊な時しか使わないものにあまりUIを書いたりはしたくないけれど、、、

data下でなくてexternal storage下にフォルダを掘ってそこに普段のファイルを置くように変更すれば、そこにサブフォルダ掘って要らない時はそこに置いておく、というやり方で良い。 運用的にはとりあえずRecycleBinがあふれたら手動で削除、でもよいし、削除されるのが計算外の挙動でも手動で戻せばよい。

少し面倒なので最初はローカルはえいっと削除してしまって、あとで考える、くらいでいいかもしれないが。

実装に自信が無ければdata下にRecycleBinとかフォルダ掘ってそこに移動、削除はdelete local cacheの時しかやらない、復旧はルート取って手動でやれ、くらいのやる気なさでもいいかもしれない(自分はルート取ってるので)

karino2 commented 4 years ago

コンフリクト時の両方のファイルをまとめて、というのはどういう感じですかね? ドライブとローカルのファイルをくっつけた一つの長いファイルを作る、とかですかね?

それだととりあえずデータが無くなる事は無いので必要最低限は満たせている。 でもコンフリクトした時に戻す作業がかったるい気もする。 長いテキストの一行だけがお互い違う時に、現状のUIだとセルが大量に出来てしまうので普通の大きなEditTextの時に比べて復旧がだるい(まぁDriveアプリで手動で直すという手はあるのでこれでもいいか?)。

コンフリクトした時はいつもローカル側にファイルのbasenameの所に括弧つきで数字を足して(ドライブに例えば既にhoge(1).txtがあったらhoge(2).txtと大きくしていく)、この新しいファイルがその瞬間にユーザーに作られたかのように扱うのは面倒ですか?

コンフリクトがあった時、 l_file(2), r_drive(3), l_drive(1) のhoge.txtは、 l_file(3), r_drive(3), l_drive(3)のhoge.txt(ドライブのが元)と、l_file(3), r_drive(3), l_drive(3)のhoge(1).txt (ローカルのhoge.txtが元)の二つになる。 l_file(3), r_drive(2), l_drive(1)でも同様。

削除と更新がぶつかるケースはいつも更新を残しても良い気もするがどうだろう? 一貫性が無くて混乱するか?

karino2 commented 4 years ago

やっぱりコンフリクトはあまり起こらないので、データロスさえなければ一番実装が楽な方法で対処すればよい気がしてきました。 一番楽な実装で好きにやってください。

karino2 commented 4 years ago

ローカルのファイルをrenameした時はどうしたらいいんでしょう? 通常のローカルのファイル削除はl_driveが残ってるけどl_fileな無い、という状態で認識出来るから、 f1がf2にrenameされると、

f1: l_file(d), l_drive(1), d_drive(1) f2: l_file(2), l_drive(無し), d_drive(無し)

の2つの状態が出来て、あとは通常のsync処理でOK?

harukawa commented 4 years ago

削除の復旧はRecycleBin的なフォルダに入れて、どう復旧していくのか具体的なことは考えてみます。

アップロードをした後はDriveのidでファイルの判別をしているので、 f1からf2にrenameしてもDBのファイル名とl_fileが更新されるだけなので、通常のsync処理でいけます。 ただdriveのほうで名前を変更すると、現状ではローカルのファイルを削除してダウンロードしないといけないことが分かったので、syncを作るときに一緒に直します。

harukawa commented 4 years ago

コンフリクトはファイル内容だけで考えていましたが、ローカルとドライブのファイル名がそれぞれ変更されたケースを想定していませんでした。 なのでファイルを分ける方向に変更して、テキストだけが変更された時は括弧つきの数字(1)を足したファイルに分離して、ファイル名が変更された場合はそのまま分離することにします。 どちらかが削除されていた場合は、とりあえず更新された側を残すことにします。

karino2 commented 4 years ago

とりあえずこのくらい考えてあれば十分ですかね。 作ってみてください。