Skip to content

Commit ea14c15

Browse files
perf(plugin-git): parallelize git show static dump
1 parent e656c81 commit ea14c15

2 files changed

Lines changed: 40 additions & 4 deletions

File tree

plugins/git/src/rpc/functions/show.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ const PATCH_CHAR_LIMIT = 200_000
99
/** Matches the window `git:log` bakes, so any visible commit has a snapshot. */
1010
const SNAPSHOT_LIMIT = 200
1111

12+
/** Read-only git detail work can run in parallel without overwhelming builds. */
13+
const DUMP_CONCURRENCY = 8
14+
1215
export interface CommitFile {
1316
path: string
1417
additions: number
@@ -189,10 +192,13 @@ export const show = defineRpcFunction({
189192
])
190193
const hashes = raw ? raw.split('\n').filter(Boolean) : []
191194

192-
const records = []
193-
for (const hash of hashes) {
194-
const output = await readCommit(git, hash, false)
195-
records.push({ inputs: [{ hash }], output })
195+
const records: { inputs: [{ hash: string }], output: CommitDetail }[] = []
196+
for (let i = 0; i < hashes.length; i += DUMP_CONCURRENCY) {
197+
const batch = hashes.slice(i, i + DUMP_CONCURRENCY)
198+
const outputs = await Promise.all(batch.map(hash => readCommit(git, hash, false)))
199+
batch.forEach((hash, index) => {
200+
records.push({ inputs: [{ hash }], output: outputs[index] })
201+
})
196202
}
197203

198204
const fallback = records[0]?.output ?? { ...EMPTY_DETAIL, isRepo: true }

plugins/git/test/git.test.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,36 @@ describe('@devframes/plugin-git (build snapshot)', () => {
216216
repo.cleanup()
217217
}
218218
})
219+
220+
it('bakes git:show records for the log snapshot window', async () => {
221+
const repo = createTempRepo()
222+
try {
223+
const ctx = await createDashboardContext(repo.dir, 'build')
224+
const dump = await collectStaticRpcDump(ctx.rpc.definitions.values(), ctx)
225+
226+
const entry = dump.manifest['git:show']
227+
expect(entry).toBeDefined()
228+
expect(entry.type).toBe('query')
229+
expect(Object.keys(entry.records)).toHaveLength(2)
230+
expect(entry.fallback).toBeTruthy()
231+
232+
const recordPaths = Object.values(entry.records as Record<string, string>)
233+
const details = recordPaths.map((path) => {
234+
return (dump.files[path].data as { output: CommitDetail }).output
235+
})
236+
237+
expect(details.map(detail => detail.subject)).toEqual([
238+
'feat: add a.txt',
239+
'init: add readme',
240+
])
241+
expect(details.every(detail => detail.isRepo && detail.found)).toBe(true)
242+
expect(details.every(detail => detail.patch === null)).toBe(true)
243+
expect(details[0].files.map(file => file.path)).toContain('a.txt')
244+
}
245+
finally {
246+
repo.cleanup()
247+
}
248+
})
219249
})
220250

221251
describe('@devframes/plugin-git (write actions)', () => {

0 commit comments

Comments
 (0)