Add retry logic and improve test timing for fetchLineNames#22
Add retry logic and improve test timing for fetchLineNames#22TinyKitten merged 3 commits intomainfrom
Conversation
fetchLineNamesで取得に失敗したIDが永続的にfetchedIdsに残り、 再取得されない問題を修正。resolvedIds(取得成功済み)と pendingIds(取得中)に分離し、失敗時は指数バックオフで 最大3回リトライする。全リトライ失敗後も新しい路線追加時に 再取得が可能になる。 https://claude.ai/code/session_01AeztrVJGigrhtYXRwbWx3r
pnpm管理のリポジトリでnpm installにより生成された package-lock.jsonを無視するように設定。 https://claude.ai/code/session_01AeztrVJGigrhtYXRwbWx3r
📝 WalkthroughWalkthroughパッケージロックの無視設定追加と、ライン名取得フックに対する per-id ライフサイクル追跡( Changes
Sequence DiagramsequenceDiagram
participant Hook as Hook (use-line-names)
participant State as State (pendingIds / resolvedIds)
participant API as GraphQL API
participant Cache as Cache (names / colors)
Hook->>State: 新しいIDを検出して pendingIds に追加
Hook->>API: fetchLineNames(ids, _retryCount)
alt API 成功(lines あり)
API-->>Hook: lines データ返却
Hook->>State: pendingIds から削除し resolvedIds に追加
Hook->>Cache: names/colors を更新
Hook->>Hook: リスナーへ通知
else API 失敗 または lines undefined
API-->>Hook: エラー / 不完全レスポンス
Hook->>State: 影響IDの pendingIds をクリア
Hook->>Hook: リトライをスケジュール(遅延: 2000ms → 4000ms → 8000ms)
alt retry 回数未達
Hook->>API: 再試行(_retryCount 増加)
else retry 上限到達
Hook-->>Hook: 以降リトライ停止
end
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
No actionable comments were generated in the recent review. 🎉 🧹 Recent nitpick comments
Comment |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
hooks/use-line-names.ts (1)
92-100:⚠️ Potential issue | 🟡 MinorLocationCardコンポーネントで毎レンダー新しい配列が生成されることによるfetch呼び出しの増加
LocationCardコンポーネント(line 92)でconst lineIds = update.line_id ? [update.line_id] : [];として毎レンダー新しい配列を生成しており、useEffect依存配列の参照が毎回変わるため、fetchLineNamesが毎レンダーで呼び出されています。fetchLineNames内部のフィルタリング(resolvedIds/pendingIdsによる重複排除)により実際のネットワークリクエストは防がれていますが、不要な関数呼び出しと依存配列チェックが発生しています。useMemoでlineIdsをメモ化するか、JSON.stringify(lineIds)を依存配列に使用することで改善してください。一方、
map.tsxとtimeline.tsxで使用されているstate.lineIdsはコンテキストから取得される値で、lineIds自体が変更されたときのみ配列参照が更新される設計となっているため、より効率的です。
🧹 Nitpick comments (2)
hooks/use-line-names.ts (2)
70-74: バッチ内の一部IDがレスポンスに含まれない場合の挙動について現在の実装では、レスポンスに
lines配列が存在すれば、リクエストした全てのnewIdsがresolvedIdsに追加されます。しかし、APIが一部のIDのみを返した場合(例:存在しないID)、そのIDも「解決済み」として扱われ、再取得されなくなります。これが意図した動作であれば問題ありませんが、存在しないIDを後で再取得する必要がある場合は、レスポンスに含まれるIDのみを
resolvedIdsに追加することを検討してください。♻️ レスポンスに含まれるIDのみを解決済みにする案
- // 取得成功: resolvedIdsに追加してpendingIdsから削除 - for (const id of newIds) { - resolvedIds.add(id); - pendingIds.delete(id); - } + // 取得成功: レスポンスに含まれるIDのみresolvedIdsに追加 + const returnedIds = new Set(lines.map((line) => String(line.id))); + for (const id of newIds) { + if (returnedIds.has(id)) { + resolvedIds.add(id); + } + pendingIds.delete(id); + }
81-89: エラー情報のロギングを検討現在の
catchブロックはエラー情報を無視しています。本番環境でのデバッグを容易にするため、エラーをログに記録することを検討してください。♻️ エラーログを追加する案
- .catch(() => { + .catch((error) => { // 取得失敗: pendingIdsから削除してリトライ + if (__DEV__) { + console.warn(`fetchLineNames failed (retry ${_retryCount}/${MAX_RETRIES}):`, error); + } for (const id of newIds) pendingIds.delete(id);
- useLineNames/useLineColorsのuseEffect依存配列をlineIds.join(",")に
変更し、配列参照ではなく値ベースで比較するように改善
- LocationCardのlineIds配列をuseMemoでメモ化し、毎レンダーの
新規配列生成を防止
https://claude.ai/code/session_01AeztrVJGigrhtYXRwbWx3r
Summary
Implemented exponential backoff retry logic for failed line name fetches and refactored tests to use fake timers for more reliable async testing.
Key Changes
Source Code (
hooks/use-line-names.ts)pendingIdsSet to prevent duplicate requests for IDs currently being fetchedfetchedIdsintoresolvedIds(successful fetches) andpendingIds(in-flight requests)linesdata in responses as retriable errorspendingIdson both success and failureTests (
lib/__tests__/use-line-names.test.ts)vi.useFakeTimers()inbeforeEachandvi.useRealTimers()inafterEachfor deterministic async testingflushPromises()utility to advance microtask queue instead of usingvi.waitFor()linesdatavi.waitFor()calls withflushPromises()for consistency and replacedsetTimeoutwaits with timer advancementConfiguration
package-lock.jsonto.gitignoreImplementation Details
https://claude.ai/code/session_01AeztrVJGigrhtYXRwbWx3r
Summary by CodeRabbit
改善
テスト
その他