canary - #6971
Merged
Merged
canary#6971
Conversation
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0153nzW9kBfL71DcfeQR3beo
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q7NJSGcnmF9rF1GRe3gcLL
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018yU3fVrZpYCCAHv1z2rTu9
* iOSで変位ゲートにより測位配信が途絶える区間を補完測位で更新し続けるようにする iOSはtimeIntervalが無視され変位ゲート(distanceFilter=10m)だけが配信を決めるため、 地下鉄のようにGPSを失い測位が同じ座標へ張り付く区間では配信が完全に止まり、位置・ 最寄り駅・到着判定・ヘッダーがまとめて凍結する。Androidは変位ゲートが0でtimeInterval が効くため同じ区間でも10秒ごとに届く。これが「Androidでは地下鉄でも更新されるのに iPhoneでは更新されない」の原因。 変位ゲートを0へ戻す選択は取らない。iOSでは約1Hz配信となり電池を著しく消費するため 実車検証を経て10mが選ばれている(#6470)。代わりに、継続測位の配信が10秒途絶えたときだけ getCurrentPositionAsyncで測位を取りに行く補完測位をiOSにだけ追加し、Androidが変位に 依らず確保している更新間隔を下回らないようにする。地上走行中は10mを数秒で超えるため 一度も発火せず、#6470が狙った停車中の取りこぼし対策も維持したまま補える。 取得した測位はhandleTrackingLocationへ通すため、重複排除・精度フィルタ・EMA・速度 フィルタの扱いは継続測位と完全に同じになる。応答が返らない取得でガードが解けず補完が 止まらないよう、間隔3回ぶんを超えた要求は見切る。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016sZFS43kKpMv5HjadBkF3x * 補完測位の取得間隔を実測10秒に直し前景・権限あり・非省電力に限定する ローカルレビュー(Fable)で見つかった4点への対応。 1. 取得間隔が実測20秒だった。固定間隔のタイマーで点検すると、補完測位が取り込んだ 測位が途絶タイマーを巻き戻すぶん必ず1回空振りし、実際の取得が閾値の2倍まで開く。 点検を固定間隔から「最後の配信から途絶時間が経つ時刻」への置き直しへ変更し、 応答を受け取った時点でも次の点検を張り直す。取得間隔を実物の handleTrackingLocationごと測る回帰テストを別ファイルで追加した(固定間隔の実装では 60秒あたり3回しか取得せず落ちる)。 2. 背景で誤発火していた。expo-locationのタスクは前景でだけ測位を即時報告し、それ以外は deferredUpdatesInterval(10秒)ぶん貯めてから報告するため、背景では正常時も配信間隔が 途絶時間以上になり地上でも発火する。加えて一発取得に使われるCLLocationManagerは allowsBackgroundLocationUpdatesを立てないので背景では測位を受け取れない。 useIsAppActiveで前景に限定する。 3. 前景権限が無い利用者(「許可せずに開始」)で取得の失敗を繰り返していた。effect開始時に getForegroundPermissionsAsyncで確認し、未許可なら点検を張らない。effectは前景復帰の たびに張り直されるため、あとから許可された場合もそこで拾う。 4. 省電力測位プロファイル中は補完測位を動かさない。このプロファイルはiOSで停車中の 測位休止(pausesUpdatesAutomatically)を許可しており(#6395)、補完測位はその休止を そのまま打ち消すため。電池優先という設定の意図を尊重し、省電力中は凍結を許容する。 選択肢(受け入れて明記/間隔を伸ばす/無効化)のうち無効化をリポジトリオーナーが選択。 あわせて、抽出したuseLocationProfileの参照安定性(崩れると測位タスクが再レンダーごとに 停止→再開する)と、遅延返答の取り込み・端末省電力モードの分岐にテストを追加した。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016sZFS43kKpMv5HjadBkF3x * 補完測位の初回点検を最後の配信時刻に合わせ時計巻き戻しで点検が飛ぶのを防ぐ CodeRabbitの指摘への対応。権限確認後の初回スケジュールが常に途絶時間ぶん待っていたため、 既に途絶した状態で前景へ戻ったとき(地下でアプリを開き直した等)に取得までさらに10秒遅れて いた。待つかどうかの判断をcheckへ一本化し、初回は即座にcheckへ入れる。未配信(0)のときだけ effect開始時刻を基準にして途絶時間ぶん待ち、起動直後に継続測位と一発取得が二重に走るのを 避ける。 あわせて、経過時間が負になる場合(端末の時計の巻き戻し)を途絶として扱う。残り時間として 使うと巻き戻し幅ぶん点検が先送りされ、補完測位が止まる。handleTrackingLocationが CLOCK_ROLLBACK_TOLERANCE_MSで同じ事故を防いでいるのと同じ理由。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016sZFS43kKpMv5HjadBkF3x * 経過時間の計測を単調増加時計へ移し端末時計の変更で補完測位が乱れないようにする CodeRabbitの指摘への対応。補完測位の途絶判定・保留見切りはどちらも「経過時間」の判定 なのに端末の時計(Date.now)で測っていた。時計が巻き戻ると残り時間が巻き戻し幅ぶん伸びて 点検が止まり、進むと保留中の要求を早く見切って重複要求を出す。 src/utils/monotonicNow.ts を追加し、記録側(handleTrackingLocation)と判定側 (useLocationHeartbeat)を同じ時計へ揃える。React Nativeはglobal.performanceを必ず 用意するため、performance.nowを使い、無い環境ではDate.nowへ退避する。 あわせて、記録の公開APIを「時刻」から「経過時間」へ変えた(getLastTrackedLocationAtMs → getMsSinceLastTrackedLocation)。時刻を返すと呼び出し側が別の時計と引き算できてしまい、 同じ事故を再発させられるため。未配信はnullで表す。 フォールバックでDate.nowが使われる環境では単調性が保証されないため、負の経過時間を 「基準が信用できない」として扱う既存のガードは残す。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016sZFS43kKpMv5HjadBkF3x * 保留中に経過時間が負になっても補完測位の要求を重ねないようにする CodeRabbitの指摘への対応。取得の応答を待っている間に経過時間が負になると (monotonicNowがDate.nowへフォールバックした環境での時計の巻き戻し)、保留の判定から 外れて1件目の応答を待たないまま2件目の要求が走っていた。 負でも「取得中」であることは変わらないので保留として扱う。ただし残り時間をそのまま 使うと見切りが巻き戻し幅ぶん先送りされる(応答が返らない要求で補完測位が止まる)ため、 待ち時間は見切り時間で頭打ちにする。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016sZFS43kKpMv5HjadBkF3x * 補完測位の見切りを時計に依存しないタイマーへ移す CodeRabbitの指摘への対応。保留の見切りを経過時間の計算で行っていたため、 monotonicNowがDate.nowへフォールバックした環境で時計が巻き戻ったまま応答が返らないと、 経過時間が負のままで見切りが成立せず、補完測位が止まる可能性があった。 要求のたびに見切りタイマー(setTimeout)を張り、応答時とアンマウント時に解除する。 見切り時は要求識別子を進めてから次の点検へ入るので、見切った要求が後から返っても 現役の要求のガードは触られない。保留中の点検は何もしない(次を置くのは応答のfinallyか 見切りタイマー)ため、保留の長さを決めるのは時計ではなくタイマーだけになる。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016sZFS43kKpMv5HjadBkF3x --------- Co-authored-by: Claude <noreply@anthropic.com>
Contributor
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Essentials Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概要
devの内容をcanaryへ昇格する。含まれる変更は #6970 / #6969 / #6966 / #6965 の 4 件と、v10.15.1 リリース(masterからの同期)。semver は 10.15.0 → 10.15.1 に上がる。変更の種類
変更内容
distanceInterval = 10(CLLocationManager.distanceFilter)だけが配信を決め、timeIntervalが無視されるため、地下鉄で座標が張り付くとlocationAtomが凍結していたuseLocationHeartbeatを追加し、継続測位がLOCATION_HEARTBEAT_STALE_THRESHOLD(10 秒 = Android が変位に依らず確保している更新間隔)を超えて途絶えたときだけgetCurrentPositionAsyncを 1 回叩くsrc/screens/Main.tsxではNEEDS_LOCATION_HEARTBEATが真のときだけFxLocationHeartbeatをマウントする(レンダーレス、表示への影響なし)<extensions>に独自要素trainlcd:accuracyを追加し、ウェイポイントごとの水平精度(m)を記録・再生できるようにしたassets/gpx/FLinerSeibu.gpxを追加(開発者向けフィクスチャ。require()されないため Metro のバンドルには入らない)setLocationの地下鉄分岐(lineType === SubwayかつisAccuracyStableが false)を実データで踏めるようになった.github/workflows/test_lab_robo.ymlを新規追加。Build Android Canary が上げたapp-devReleaseアーティファクトをrun-id指定で取得するだけでビルドはしないFlow.yamlを削除.claude/skills/review-with-fable/SKILL.mdを追加。アプリのコードには触れていないmaster→dev同期 (v10.15.1🎉 #6955 / dev<-master #6968)MARKETING_VERSION/ AndroidversionNameを更新テスト
npm run lintが通ることnpm testが通ることnpm run typecheckが通ること各変更は
devへマージされる前にレビューと CI を通過済み。canary で確認したいこと
NEEDS_LOCATION_HEARTBEATが偽なのでフックはマウントされない想定)関連Issue
#6970、#6969、#6966、#6965
スクリーンショット(任意)
UI 変更なし: 含まれる変更は測位パイプライン(
src/hooks/**/src/utils/**/src/constants/**)、CI ワークフロー、ドキュメント、開発者向け GPX フィクスチャのみです。src/screens/Main.tsxの差分はレンダーレスなFxLocationHeartbeatを条件付きでマウントするだけで、画面レイアウトや表示文言には変化がありません。🤖 Generated with Claude Code
https://claude.ai/code/session_01PezZM56jUs2qMBnpru5kTS