Skip to content

fix(kit): retry transient offline reset locks - #107

Merged
rdlabo merged 3 commits into
mainfrom
fix/retry-offline-reset-sqlite-lock
Sep 11, 2026
Merged

rdlabo merged 3 commits into
mainfrom
fix/retry-offline-reset-sqlite-lock

Conversation

@rdlabo

@rdlabo rdlabo commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Summary

  • retry transient SQLITE_BUSY and SQLITE_LOCKED failures while deleting or closing offline databases during reset and encryption migration
  • bound retries to 50 ms, 150 ms, and 300 ms while preserving immediate failure for non-transient errors and the final native error after exhaustion
  • detect wrapped SQLite lock failures through Error.cause and AggregateError.errors with cycle-safe traversal
  • preserve marker ordering and the existing delete-and-close resource cleanup contract

Verification

  • npx ng test kit --watch=false (56 files, 1,078 tests)
  • ESLint on all changed files
  • Prettier on all changed files
  • git diff --check

Review cycles

  • manager review: approved after wrapped-error and retry-boundary coverage was added
  • third-party acceptance review: accepted after delete, close, non-lock, exhaustion, and marker behavior were verified

Fixes FOODLABEL-APP-CR


Devin Review

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 potential issues.

Devin Review

Comment thread projects/kit/offline/src/lib/offline-repository-concurrency.ts Outdated
Comment thread projects/kit/offline/src/lib/offline-local-reset.ts
@rdlabo

rdlabo commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

/devin 再度レビューして。 #104 との関係についても整理して

@devin-ai-integration

Copy link
Copy Markdown
Contributor

View Devin session

Co-Authored-By: rdlabo <sakakibara@rdlabo.jp>
@devin-ai-integration

Copy link
Copy Markdown
Contributor

再レビュー結果(16d746a まで)

修正した点(c78525d)

混在 AggregateError を即時伝播する 16d746a の方針は妥当ですが、visited を兄弟ブランチ間で共有していたため、全要素が一時的ロックである aggregate が「非一時的」と誤判定される false negative がありました。走査済みオブジェクトが二度目に現れると null を返し、if (!reason) return null で aggregate 全体が非一時的になるためです。

再現していた 2 ケース(どちらも修正前は false):

const nativeLock = new Error('... message: database is locked');
isTransientSqliteLockError(new AggregateError([
  new Error('delete failed', { cause: nativeLock }),
  new Error('close failed', { cause: nativeLock }),
])); // 修正前 false → 再試行されない

const locked = new Error('SQLITE_BUSY');
isTransientSqliteLockError(new AggregateError([locked, locked])); // 修正前 false

前者は deleteAndCloseOfflineDatabase が投げる AggregateError([deletion.error, closing.error]) の形そのもの(delete/close が同一のネイティブロックを cause に持つ)なので、実際に踏み得ます。影響は「再試行されず即失敗」= fail-safe 側ですが、本 PR の目的を打ち消します。

修正は visited を兄弟ごとにコピーし、サイクル保護を経路単位に限定するだけです(cause 連鎖は単一経路なので従来どおり)。回帰テスト 2 件を追加、kit 全 1,081 テスト・ESLint・Prettier 通過。

残る指摘(任意・本 PR ではブロッカーではない)

  1. 再試行ループの重複: settleOfflineResetOperationsqlite-offline-repository.tsopenCommunitySqliteDatabase と構造も遅延配列 [50, 150, 300] も同一です。offline-repository-concurrency.tsretryTransientSqliteLock(operation, delays) を切り出して両者から使う方が、今後の遅延調整が片方だけに入る事故を防げます。
  2. cold start の待ち時間: 1 DB あたり delete/close それぞれ最大 4 試行なので、最悪 500ms×2 = 約 1 秒のスリープが Angular bootstrap 前に入り、対象 DB 数だけ積み上がります(kitCompatibleDatabaseNames が複数の製品では体感し得る)。意図どおりなら記載不要ですが、上限は把握しておく価値があります。
  3. テストの遅延検証: 追加テストは setTimeout を同期実行モックに置き換えているため、遅延値そのもの(50/150/300 の順序)は未検証です。挙動検証としては十分なので指摘のみ。

marker 書き込み順序、delete 失敗時も close を実行する後始末契約、非一時的エラーの即時伝播はいずれも維持されています。

#104 との関係

#104 #107
対象 offline-network.service.ts / offline.interceptor.ts / offline-coordinator.service.ts / offline-request-policy.ts offline-local-reset.ts / offline-repository-concurrency.ts
内容 API 到達性の手動検証(verifyConnection、8s タイムアウト、single-flight、観測順序保証) ネイティブ SQLite の reset / 暗号化移行時の一時的ロック再試行
種別 機能追加 クラッシュ修正(FOODLABEL-APP-CR)

@rdlabo
rdlabo merged commit bca274c into main Sep 11, 2026
14 checks passed
@rdlabo
rdlabo deleted the fix/retry-offline-reset-sqlite-lock branch September 11, 2026 15:48
@github-actions

Copy link
Copy Markdown

npm beta packages published

CI passed for the merge commit bca274cf9d55. Install the immutable package set with:

npm install @rdlabo/ionic-angular-kit@22.0.2-beta.pr107.shabca274cf9d55 @rdlabo/ionic-angular-photo-editor@22.0.2-beta.pr107.shabca274cf9d55 @rdlabo/ionic-angular-scroll-header@22.0.2-beta.pr107.shabca274cf9d55 @rdlabo/ngx-cdk-scroll-strategies@22.0.2-beta.pr107.shabca274cf9d55

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

Successfully merging this pull request may close these issues.

1 participant