-
Notifications
You must be signed in to change notification settings - Fork 0
⚡ perf: Optimize 2D array allocation in heatmap generation #449
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,6 +6,17 @@ import { buildHourlyHeatmapFromCommitDates, getMostActiveDayFromCalendar, getMos | |
| import { logger } from "@/lib/logger"; | ||
|
|
||
|
|
||
|
|
||
| const EMPTY_HEATMAP = [ | ||
| [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], | ||
| [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], | ||
| [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], | ||
| [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], | ||
| [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], | ||
| [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], | ||
| [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], | ||
| ]; | ||
|
|
||
|
Comment on lines
+9
to
+19
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Prompt To Fix With AIThis is a comment left during a code review.
Path: src/lib/githubYearInReview.ts
Line: 9-19
Comment:
**共有ミュータブル定数を参照のまま返している問題**
`EMPTY_HEATMAP` はモジュールレベルで定義された共有オブジェクトですが、`return EMPTY_HEATMAP` で同一の参照をそのまま返しています。Next.js のサーバー環境ではモジュールレベルの変数はリクエスト間で共有されるため、呼び出し元が返り値の配列を変更した場合(例: `heatmap[0][0] = 99`)、以降のすべてのエラーレスポンスが汚染されたデータを返すサイレントなデータ破損が発生します。現在の `route.ts` では `NextResponse.json()` でシリアライズするだけなので問題は顕在化していませんが、将来の変更で簡単に破壊される脆弱な設計です。
`return EMPTY_HEATMAP` の代わりに `return EMPTY_HEATMAP.map(row => [...row])` でディープコピーを返すか、モジュール定数を廃止してその場で新たな配列を生成する方式に戻すことを推奨します。
How can I resolve this? If you propose a fix, please make it concise. |
||
| const YEAR_IN_REVIEW_QUERY = `query($login: String!, $from: DateTime!, $to: DateTime!, $maxRepositories: Int!) { | ||
| user(login: $login) { | ||
| id | ||
|
|
@@ -306,7 +317,7 @@ export async function fetchCommitActivityHeatmap(username: string, year: number, | |
| const topRepository = mergeTopRepository(reposResponse.user.contributionsCollection); | ||
|
|
||
| if (!topRepository) { | ||
| return Array.from({ length: 7 }, () => Array.from({ length: 24 }, () => 0)); | ||
| return EMPTY_HEATMAP; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| } | ||
|
|
||
| const [owner, repo] = topRepository.name.split("/"); | ||
|
|
@@ -321,7 +332,7 @@ export async function fetchCommitActivityHeatmap(username: string, year: number, | |
| handleRateLimit(res); | ||
| } | ||
| if (!res.ok) { | ||
| return Array.from({ length: 7 }, () => Array.from({ length: 24 }, () => 0)); | ||
| return EMPTY_HEATMAP; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| } | ||
|
|
||
| const commits = (await res.json()) as GitHubCommit[]; | ||
|
|
||
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.
Returning a shared global mutable array (
EMPTY_HEATMAP) fromfetchCommitActivityHeatmapis highly dangerous, especially in a server-side environment (server-only). If any caller or consumer mutates the returned heatmap, it will pollute the sharedEMPTY_HEATMAPinstance across all subsequent requests and users.To prevent cross-request state pollution while keeping the performance benefits of static array literals, we should define a helper function
createEmptyHeatmapthat returns a fresh array literal on each call. Ensure the function has an explicit return type to maintain type safety.References