fix(offline): isolate synchronization failure boundaries - #66
Conversation
✅ Deploy Preview for rdlabo-ionic-angular-library ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
| if (fatalPullFailure !== null) { | ||
| // Auth/upgrade recovery only — never arm the 1s automatic flush retry. | ||
| // Post-send ACK already removed the command; reconciliation markers remain for later recovery. | ||
| // Only the owning generation may clear the timer — a stale fatal must not disarm a | ||
| // newer session's already-armed retry_wait / post-pull retry. | ||
| if (this.#isCurrent(generation)) this.#scheduleRetry(null); | ||
| throw fatalPullFailure; |
There was a problem hiding this comment.
🟡 認証やスキーマ不一致の同期エラーが起きると、再送待ちの操作の自動再試行が止まる
再送待ちの操作に対して直前に設定された自動再試行の予約が取り消され (#scheduleRetry(null) at projects/kit/offline/src/lib/offline-sync.service.ts:1020)、致命的な同期エラーの後に予約が空のままになるため、未送信の操作が自動では再送されなくなります。
Impact: 認証切れやスキーマ不一致が一度起きると、送信待ちのユーザー操作がアプリ側で別の操作が行われるまでサーバーに届かないままになります。
タイマー解除の経路 (#refreshState が張った retry_wait タイマーを fatal 分岐が消す)
#runFlush は fatal 判定の直前に await this.#refreshState(generation) を実行します (projects/kit/offline/src/lib/offline-sync.service.ts:1014)。#refreshState は retry_wait 状態のコマンドのうち最も早い retryAt で #scheduleRetry を呼び、指数バックオフのタイマーを張ります (projects/kit/offline/src/lib/offline-sync.service.ts:1618-1621)。
その直後の fatal 分岐が #scheduleRetry(null) を呼ぶと、#scheduleRetry は既存タイマーを clearTimeout して何も張り直しません (projects/kit/offline/src/lib/offline-sync.service.ts:1624-1635)。コメントの意図は「1秒の自動 post-pull retry を張らない」ことですが、実装は同一世代で既に張られている retry_wait のバックオフタイマーも一緒に消します。
再現例: scope A のコマンド送信が HTTP 500 で失敗して retry_wait になり、続く scope B の post-send pull が 401/403/409 を返す。このとき A の再試行タイマーが消え、refreshSession / reloadPendingCommands / ネットワーク再接続などで #refreshState が再度走るまで自動再送は行われません。
Prompt for agents
projects/kit/offline/src/lib/offline-sync.service.ts の #runFlush にある fatal 分岐が #scheduleRetry(null) を呼んでいるため、直前の #refreshState が retry_wait コマンド向けに張ったバックオフタイマーまで解除されてしまう。意図は『致命的 pull 失敗のときに 1 秒の自動 post-pull retry を張らない』ことなので、既存の retry_wait タイマーは保持したい。#refreshState が既に正しいタイマーを設定している点を踏まえ、fatal 経路では追加でタイマーを張らない(=何もしない)か、retry_wait コマンドから再計算した次回 retryAt を渡すように修正することを検討してほしい。合わせて『fatal 発生時でも既存 retry_wait の自動再送タイマーが残る』ことを検証するテストを追加すると良い。
Was this helpful? React with 👍 or 👎 to provide feedback.
Summary
Verification