mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
fix: resolve checkpoint initialization timeout in large repositories
- Add timeout handling for initial git staging operation (5 seconds) - Add --ignore-errors flag to git add command for better error handling - Add isInitialCall parameter to allow unlimited time for first initialization - Prevent blocking on large repositories during checkpoint setup This fix addresses issue #7843 where checkpoints would fail to initialize in large repositories due to the git add operation taking longer than the 15-second timeout limit.
This commit is contained in:
parent
7cd6520302
commit
a7f2acfd57
3 changed files with 32 additions and 11 deletions
|
|
@ -18,7 +18,11 @@ import { CheckpointServiceOptions, RepoPerTaskCheckpointService } from "../../se
|
|||
|
||||
export async function getCheckpointService(
|
||||
task: Task,
|
||||
{ interval = 250, timeout = 15_000 }: { interval?: number; timeout?: number } = {},
|
||||
{
|
||||
interval = 250,
|
||||
timeout = 15_000,
|
||||
isInitialCall = false,
|
||||
}: { interval?: number; timeout?: number; isInitialCall?: boolean } = {},
|
||||
) {
|
||||
if (!task.enableCheckpoints) {
|
||||
return undefined
|
||||
|
|
@ -67,13 +71,12 @@ export async function getCheckpointService(
|
|||
}
|
||||
|
||||
if (task.checkpointServiceInitializing) {
|
||||
await pWaitFor(
|
||||
() => {
|
||||
console.log("[Task#getCheckpointService] waiting for service to initialize")
|
||||
return !!task.checkpointService && !!task?.checkpointService?.isInitialized
|
||||
},
|
||||
{ interval, timeout },
|
||||
)
|
||||
// For initial calls, don't apply timeout to allow large repositories to initialize
|
||||
const waitOptions = isInitialCall ? { interval } : { interval, timeout }
|
||||
await pWaitFor(() => {
|
||||
console.log("[Task#getCheckpointService] waiting for service to initialize")
|
||||
return !!task.checkpointService && !!task?.checkpointService?.isInitialized
|
||||
}, waitOptions)
|
||||
if (!task?.checkpointService) {
|
||||
task.enableCheckpoints = false
|
||||
return undefined
|
||||
|
|
|
|||
|
|
@ -1661,7 +1661,8 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
|
|||
|
||||
private async initiateTaskLoop(userContent: Anthropic.Messages.ContentBlockParam[]): Promise<void> {
|
||||
// Kicks off the checkpoints initialization process in the background.
|
||||
getCheckpointService(this)
|
||||
// Pass isInitialCall=true to allow unlimited time for large repositories
|
||||
getCheckpointService(this, { isInitialCall: true })
|
||||
|
||||
let nextUserContent = userContent
|
||||
let includeFileDetails = true
|
||||
|
|
|
|||
|
|
@ -105,7 +105,21 @@ export abstract class ShadowCheckpointService extends EventEmitter {
|
|||
await git.addConfig("user.name", "Roo Code")
|
||||
await git.addConfig("user.email", "noreply@example.com")
|
||||
await this.writeExcludeFile()
|
||||
await this.stageAll(git)
|
||||
|
||||
// For initial commit, stage files but with a timeout to prevent hanging on large repos
|
||||
// Use a promise race to ensure we don't wait forever
|
||||
const stagePromise = this.stageAll(git)
|
||||
const timeoutPromise = new Promise<void>((resolve) => {
|
||||
setTimeout(() => {
|
||||
this.log(
|
||||
`[${this.constructor.name}#initShadowGit] Initial staging timed out after 5 seconds, proceeding with empty commit`,
|
||||
)
|
||||
resolve()
|
||||
}, 5000) // 5 second timeout for initial staging
|
||||
})
|
||||
|
||||
await Promise.race([stagePromise, timeoutPromise])
|
||||
|
||||
const { commit } = await git.commit("initial commit", { "--allow-empty": null })
|
||||
this.baseHash = commit
|
||||
created = true
|
||||
|
|
@ -145,11 +159,14 @@ export abstract class ShadowCheckpointService extends EventEmitter {
|
|||
|
||||
private async stageAll(git: SimpleGit) {
|
||||
try {
|
||||
await git.add(".")
|
||||
// Add --ignore-errors flag to handle permission issues gracefully
|
||||
// This prevents the operation from failing on files with permission issues
|
||||
await git.add([".", "--ignore-errors"])
|
||||
} catch (error) {
|
||||
this.log(
|
||||
`[${this.constructor.name}#stageAll] failed to add files to git: ${error instanceof Error ? error.message : String(error)}`,
|
||||
)
|
||||
// Don't throw - allow the operation to continue with whatever files were successfully staged
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue