Skip to content

Commit 2c75868

Browse files
committed
Added Concurrent processing for faster Execution
1 parent 67b76c6 commit 2c75868

File tree

1 file changed

+59
-33
lines changed

1 file changed

+59
-33
lines changed

src/lib/statsProvider.tsx

Lines changed: 59 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ interface CommunityStatsProviderProps {
6666

6767
const GITHUB_ORG = "recodehive";
6868
const POINTS_PER_PR = 10;
69+
const MAX_CONCURRENT_REQUESTS = 5; // Limit concurrent requests to avoid rate limiting
6970

7071
export function CommunityStatsProvider({ children }: CommunityStatsProviderProps) {
7172
const {
@@ -128,6 +129,58 @@ export function CommunityStatsProvider({ children }: CommunityStatsProviderProps
128129
return mergedPRs;
129130
}, []);
130131

132+
// NEW: Concurrent processing function with controlled concurrency
133+
const processBatch = useCallback(async (
134+
repos: any[],
135+
headers: Record<string, string>
136+
): Promise<{ contributorMap: Map<string, Contributor>; totalMergedPRs: number }> => {
137+
const contributorMap = new Map<string, Contributor>();
138+
let totalMergedPRs = 0;
139+
140+
// Process repos in batches to control concurrency
141+
for (let i = 0; i < repos.length; i += MAX_CONCURRENT_REQUESTS) {
142+
const batch = repos.slice(i, i + MAX_CONCURRENT_REQUESTS);
143+
144+
const promises = batch.map(async (repo) => {
145+
if (repo.archived) return { mergedPRs: [], repoName: repo.name };
146+
147+
try {
148+
const mergedPRs = await fetchMergedPRsForRepo(repo.name, headers);
149+
return { mergedPRs, repoName: repo.name };
150+
} catch (error) {
151+
console.warn(`Skipping repo ${repo.name} due to error:`, error);
152+
return { mergedPRs: [], repoName: repo.name };
153+
}
154+
});
155+
156+
// Wait for current batch to complete
157+
const results = await Promise.all(promises);
158+
159+
// Process results from this batch
160+
results.forEach(({ mergedPRs }) => {
161+
totalMergedPRs += mergedPRs.length;
162+
163+
mergedPRs.forEach((pr) => {
164+
const username = pr.user.login;
165+
if (!contributorMap.has(username)) {
166+
contributorMap.set(username, {
167+
username,
168+
avatar: pr.user.avatar_url,
169+
profile: pr.user.html_url,
170+
points: 0,
171+
prs: 0,
172+
});
173+
}
174+
const contributor = contributorMap.get(username)!;
175+
contributor.prs++;
176+
contributor.points += POINTS_PER_PR;
177+
});
178+
});
179+
}
180+
181+
return { contributorMap, totalMergedPRs };
182+
}, [fetchMergedPRsForRepo]);
183+
131184
const fetchAllStats = useCallback(async (signal: AbortSignal) => {
132185
setLoading(true);
133186
setError(null);
@@ -143,7 +196,7 @@ export function CommunityStatsProvider({ children }: CommunityStatsProviderProps
143196
Accept: "application/vnd.github.v3+json",
144197
};
145198

146-
// Fetch general organization stats
199+
// Fetch general organization stats (unchanged)
147200
const orgStats: GitHubOrgStats = await githubService.fetchOrganizationStats(signal);
148201
setGithubStarCount(orgStats.totalStars);
149202
setGithubContributorsCount(orgStats.totalContributors);
@@ -152,38 +205,11 @@ export function CommunityStatsProvider({ children }: CommunityStatsProviderProps
152205
setGithubDiscussionsCount(orgStats.discussionsCount);
153206
setLastUpdated(new Date(orgStats.lastUpdated));
154207

155-
// Fetch leaderboard data
208+
// Fetch leaderboard data with concurrent processing
156209
const repos = await fetchAllOrgRepos(headers);
157-
const contributorMap = new Map<string, Contributor>();
158-
let totalMergedPRs = 0;
159-
160-
for (const repo of repos) {
161-
if (repo.archived) continue;
162-
const repoName = repo.name;
163-
try {
164-
const mergedPRs = await fetchMergedPRsForRepo(repoName, headers);
165-
totalMergedPRs += mergedPRs.length;
166-
167-
for (const pr of mergedPRs) {
168-
const username = pr.user.login;
169-
if (!contributorMap.has(username)) {
170-
contributorMap.set(username, {
171-
username,
172-
avatar: pr.user.avatar_url,
173-
profile: pr.user.html_url,
174-
points: 0,
175-
prs: 0,
176-
});
177-
}
178-
const contributor = contributorMap.get(username)!;
179-
contributor.prs++;
180-
contributor.points += POINTS_PER_PR;
181-
}
182-
} catch (repoErr) {
183-
console.warn(`Skipping repo ${repoName} due to error:`, repoErr);
184-
continue;
185-
}
186-
}
210+
211+
// NEW: Use concurrent processing instead of sequential
212+
const { contributorMap, totalMergedPRs } = await processBatch(repos, headers);
187213

188214
const sortedContributors = Array.from(contributorMap.values()).sort(
189215
(a, b) => b.points - a.points || b.prs - a.prs
@@ -210,7 +236,7 @@ export function CommunityStatsProvider({ children }: CommunityStatsProviderProps
210236
} finally {
211237
setLoading(false);
212238
}
213-
}, [token, fetchAllOrgRepos, fetchMergedPRsForRepo]);
239+
}, [token, fetchAllOrgRepos, processBatch]);
214240

215241
const clearCache = useCallback(() => {
216242
githubService.clearCache();

0 commit comments

Comments
 (0)