Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 39 additions & 31 deletions src/lib/github.ts
Original file line number Diff line number Diff line change
Expand Up @@ -685,12 +685,46 @@ export const fetchActivity = cache(async function fetchActivity(
// Suppress unhandled promise rejections for subsequent pages if we break early or throw
promises.forEach((p) => p.catch((e) => logger.error("Event fetch promise rejected:", e)));

for (const p of promises) {
try {
const events = await p;
allEvents.push(...events);
// 曜日×時間帯ヒートマップ (7×24)
// 割り当てのオーバーヘッドを減らすために静的な 2D 配列リテラルを使用
const heatmap: number[][] = [
[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]
];

const eventCountMap = new Map<string, number>();
const dayCache = new Map<string, number>();

const results = await Promise.allSettled(promises);

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.

P2 Short Pages Wait For Later Fetches

When page 1 has fewer than 100 events, the function still waits for page 2 and page 3 to settle before it can return. The old page-order loop could return after the short page, but Promise.allSettled(promises) waits for results that are discarded by the later break, so a slow or stalled later GitHub response can delay activity data for small accounts.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/lib/github.ts
Line: 703

Comment:
**Short Pages Wait For Later Fetches**

When page 1 has fewer than 100 events, the function still waits for page 2 and page 3 to settle before it can return. The old page-order loop could return after the short page, but `Promise.allSettled(promises)` waits for results that are discarded by the later `break`, so a slow or stalled later GitHub response can delay activity data for small accounts.

How can I resolve this? If you propose a fix, please make it concise.

for (const result of results) {
if (result.status === "fulfilled") {
const events = result.value;
for (const event of events) {
allEvents.push(event);
const createdAt = event.created_at;
const datePart = createdAt.slice(0, 10);

let day = dayCache.get(datePart);
if (day === undefined) {
day = new Date(datePart).getUTCDay(); // 0=Sun, 6=Sat
dayCache.set(datePart, day);
}

// Fast hour extraction from YYYY-MM-DDTHH:MM:SSZ
const charCodeZero = 48; // '0'.charCodeAt(0)
const hour = (createdAt.charCodeAt(11) - charCodeZero) * 10 + (createdAt.charCodeAt(12) - charCodeZero);
heatmap[day][hour]++;

eventCountMap.set(event.type, (eventCountMap.get(event.type) ?? 0) + 1);
}
if (events.length < 100) break;
} catch (error) {
} else {
const error = result.reason;
if (
error instanceof UserNotFoundError ||
error instanceof RateLimitError
Expand All @@ -701,32 +735,6 @@ export const fetchActivity = cache(async function fetchActivity(
}
}

// 曜日×時間帯ヒートマップ (7×24)
const heatmap: number[][] = Array.from({ length: 7 }, () =>
Array.from({ length: 24 }, () => 0)
);

const eventCountMap = new Map<string, number>();
const dayCache = new Map<string, number>();

for (const event of allEvents) {
const createdAt = event.created_at;
const datePart = createdAt.slice(0, 10);

let day = dayCache.get(datePart);
if (day === undefined) {
day = new Date(datePart).getUTCDay(); // 0=Sun, 6=Sat
dayCache.set(datePart, day);
}

// Fast hour extraction from YYYY-MM-DDTHH:MM:SSZ
const charCodeZero = '0'.charCodeAt(0);
const hour = (createdAt.charCodeAt(11) - charCodeZero) * 10 + (createdAt.charCodeAt(12) - charCodeZero);
heatmap[day][hour]++;

eventCountMap.set(event.type, (eventCountMap.get(event.type) ?? 0) + 1);
}

const eventBreakdown = Array.from(eventCountMap.entries())
.sort((a, b) => b[1] - a[1])
.map(([type, count]) => ({ type, count }));
Expand Down
Loading