-
Notifications
You must be signed in to change notification settings - Fork 111
Conversation
Covid19Radar/Tests/Covid19Radar.UnitTests/Services/Migration/VersionMigrationServiceTests.cs
Outdated
Show resolved
Hide resolved
二日寝かせたらもっといい方法らしきものを思いついたのでやってみる。 |
もっといい方法というのは、バージョンごとのMigratorをリストに積んで順次実行するものだったのだけど、実際にやろうとしたらうまくいかなかった。 |
しばらく寝かしたらもっといい方法が思い浮かぶかと思ったけどそうでもなかったのでReady for reviewした。 |
rebased |
Covid19Radar/Covid19Radar.Android/Services/Migration/Migrator123.cs
Outdated
Show resolved
Hide resolved
Covid19Radar/Covid19Radar.Android/Services/Migration/Migrator123.cs
Outdated
Show resolved
Hide resolved
Covid19Radar/Covid19Radar.Android/Services/Migration/Migrator123.cs
Outdated
Show resolved
Hide resolved
Covid19Radar/Covid19Radar/Services/Migration/VersionMigrationService.cs
Outdated
Show resolved
Hide resolved
ひとまずconflictを解消 |
@keiji |
WorkManagerMigrator will be executed as Setup on migration process. Because latest worker registration must be only once.
…adcastReceiver will be killed by the system.
@keiji マイグレーション処理の実行タイミングについて 2 点ほど理由を確認させてください。
|
Covid19Radar/Covid19Radar.Android/Services/Migration/MigrationProcessService.cs
Show resolved
Hide resolved
Covid19Radar/Covid19Radar.iOS/Services/Migration/MigrationProcessService.cs
Show resolved
Hide resolved
Covid19Radar/Covid19Radar/Services/Migration/MigrationService.cs
Outdated
Show resolved
Hide resolved
Covid19Radar/Covid19Radar/Services/Migration/MigrationService.cs
Outdated
Show resolved
Hide resolved
Covid19Radar/Covid19Radar/Services/Migration/MigrationService.cs
Outdated
Show resolved
Hide resolved
return VERSION_1_0_0; | ||
} | ||
|
||
private async Task MigrateAsync(Version? fromVersion) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
理由があってnullableにしているので接触的に明示していきたいところですが、#nullable
を置かないと警告が表示される。これをどうするかという話ですね。
今のところコード規約がないので、警告の解消を優先すれば最小限の範囲で#nullable
を付けるのも良いかなと思いました。
しかしその場合、あとから規約としてクラス全体に#nullableを付ける(プロジェクト設定で一括指定したり?)など齟齬が発生した場合に差分が大きくなりますので、コード規約が定まってから手当てしても遅くはないだろうなと思って現状にした経緯があります。
開発チーム内で現状、 #nullable に関する指針が無ければ、警告は一旦このままにしておいて、将来的に方針が定まり次第解消という方向が良いかなと思いますが、いかがでしょうか。
限定的な指定も含めてどちらでも対応できるので、ご意見をお聞かせください。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
開発チーム内で現状、 #nullable に関する指針が無ければ
はい。現在指針はありません。
このコードとして理想的な実装になっていたほうがいいとも思いますが、たしかに指針があるわけではないので一旦このままで良いです。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ずいぶん前にもらってる #35 にもありますね。
いっそプロジェクトファイルでNull許容を有効にしてしまっても良いような気がしますが、このPRでやるのが良いかと言われれば 🤔 です。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
とはいえ色のつく警告を放置は気持ち悪いので、クラスファイルの最初と最後に#nullable enable/disable
で対応しました。
_loggerService.Debug($"appVersion entry is not found in Preferences."); | ||
return null; | ||
} | ||
var appVersion = _preferencesService.GetValue<string>(PreferenceKey.AppVersion, FIRST_VERSION); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
こちらもVisuslStudioにより修正候補が出ていますが、<string>
部分は省略可です。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
var fromVersion = PreferenceVersion; | ||
fromVersion = fromVersion is null ? GuessVersion() : fromVersion; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
var fromVersion = PreferenceVersion ?? GuessVersion();
としたほうがいいと思います。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
} | ||
} | ||
|
||
var currentVersion = CurrentAppVersion; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ローカル変数に入れる必要は無いと思います
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
あ、すみません。CurrentAppVersionはプロパティですが都度読み込み処理がされるんですね。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
各プロパティはコンストラクタのタイミングのみで読み込むのでは都合悪いでしょうか?
できるならそのほうがわかりやすいかと思います。
都度読み込む必要があるならメソッドにしたほうがわかりやすいかもしれません。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UpdateAppVersionPreference
で値を書き換える場合があるので、常に最新の値を読み込めるようにしています。
その上で、当該処理ではローカル変数currentVersion
に格納してしまっていますし、UpdateAppVersionPreference
との対象もわかりづらいので良くないですね。
この部分は考え直します。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CurrentAppVersionはアプリのバージョンなので固定でした。
コンストラクタからEssentialServiceを使うとエラーが起きてスタックすることがわかったので、呼び出しのときに変数を取って使い回すようにしてあります。
UpdateAppVersionPreference
もわかりにくかったのでSet/Getの組み合わせのメソッドを用意しました。
} | ||
} | ||
|
||
private Task<bool> DetectDowngradeAsync() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
非同期で動作するようなものではないので、戻り値boolのメソッドで良いと思います。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ダウングレードなしで行くことになったので、このメソッドは削除になりました。
if (await DetectDowngradeAsync()) | ||
{ | ||
_loggerService.Warning("Downgrade is detected. All data will be cleared."); | ||
|
||
await ClearAllDataAsync(); | ||
|
||
_loggerService.Info("All data cleared."); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ダウングレード時のみということは、一般ユーザ向けとしては不要なコードですね。
デバッグ用としても、ダウングレードする際は一旦アンインストールするべきで不要なコードだと思います。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ありがとうございます。
Androidの場合は常に正式リリースのバージョンは上がるばかりで、下がることはない(ダウングレードはない)という認識です。
一方、ぼくはiOSの事はよくわかっていないのですが、そちらも同様でしょうか。AppStoreからバージョン指定して落とせるみたいな事はなさそうでしょうか。
ないようであれば当該部分は削除します。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
はい。iOSでも同じくダウングレードはできないと思います。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ダウングレードはないのでこの周辺の処理は削除します。
念のためログだけ仕込んでおきます。
はい。その認識ですが、確認はしておいた方がいいですね。
これはExposureWindow modeの際に指摘をもらったのですが「BroadcastReceiverであまり長い時間処理をすると、システムによって強制停止される可能性がある」というAndroid的な事情に対応するためです。 時間としてはだいたい10秒で、今回のマイグレーション処理でこれを越えることはなさそうなのですが、しかし今後どうなるかわからないので安全策としてWorkManagerを使っています。 一方、ご指摘の通り、アプリ起動時に発生するマイグレーションとアップデート時のBroadcastReceiverから起動するマイグレーションが衝突する可能性はありますね。 |
…ProcessService.cs Co-authored-by: cocoa-dev <69558847+cocoa-dev@users.noreply.github.com>
…referenceVersion.
IEssentialsService could not use in constructor.
string[] oldWorkName = { | ||
"exposurenotification", | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
そうか……この間のsyncでここ変わったんですね。対応します!
Issue 番号 / Issue ID
目的 / Purpose
アップデート時のメンテナンスコストを低減するため、バージョンアップ(アップデート)時に、特定のバージョンから最新バージョンまでの移行処理を一元的に行う仕組みを用意する。
破壊的変更をもたらしますか / Does this introduce a breaking change?
Pull Request の種類 / Pull Request type
検証方法 / How to test
コードの入手 / Get the code
コードの検証 / Test the code
確認事項 / What to check
その他 / Other information
検証用の実証。
マイグレーション
マイグレーション関係の処理は各プロジェクトの
Services/Migration
内に集約している。Covid19Radar/Services/Migration/MigrationService.cs
マイグレーションを統括するMigrationService
が定義されている。IMigrationProcessService
には、マイグレーションが必要となるバージョンについてメソッドとして規定する(マイグレーションが発生しないバージョンは加えなくて良い)。IMigrationProcessService
は、IoCを通じてプラットフォーム固有のマイグレーション処理をMigrationService
に提供する。マイグレーションの実行は、
MigrationService
のメソッドMigrateAsync(Version? fromVersion)
で行う。現在のバージョン(fromVersion)に対してどのバージョンのマイグレーションが必要かを判断して実行する。
マイグレーションは、2つの要素からなる。
一つは共通プロジェクト側のデータのマイグレーション(たとえばApplicationPropertyServiceからPreferenceへの移行)。
もう一つはプラットフォーム固有のマイグレーション(たとえばWorkManagerのキャンセル処理)。
プラットフォーム固有のマイグレーションは、各プラットフォームプロジェクトが、IoCを通じて
IMigrationProcessService
の実装として提供する。マイグレーションの実行タイミング
Android
マイグレーションは2つのタイミングで実行される。
一つ目は、アプリがアップデートしたタイミング。これはアプリがアップデートしたタイミングでシステムが呼び出すIntent(
android.intent.action.MY_PACKAGE_REPLACED
)を受け取るAppVersionUpgradeReceiverを通じて実行される。二つ目は、バックグラウンドでの診断キーの取得と接触確認を行うバックグルアンド処理内。
iOS
マイグレーションは2つのタイミングで実行される。
一つ目は、アプリが起動したタイミング。
二つ目は、バックグラウンドでの診断キーの取得と接触確認を行うバックグラウンド処理内。