fix: clean goroutine exit in timeout message helpers
Add done channel to runGitCmdWithTimeoutMsg and runCmdWithTimeoutMessage so goroutines exit immediately when command completes, rather than waiting for the full timeout duration. Follow-up to PR #678. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -2156,17 +2156,21 @@ func checkOrphanedChildrenInJSONL(jsonlPath string) (*OrphanedChildren, error) {
|
|||||||
// runGitCmdWithTimeoutMsg runs a git command and prints a helpful message if it takes too long.
|
// runGitCmdWithTimeoutMsg runs a git command and prints a helpful message if it takes too long.
|
||||||
// This helps when git operations hang waiting for credential/browser auth.
|
// This helps when git operations hang waiting for credential/browser auth.
|
||||||
func runGitCmdWithTimeoutMsg(ctx context.Context, cmd *exec.Cmd, cmdName string, timeoutDelay time.Duration) ([]byte, error) {
|
func runGitCmdWithTimeoutMsg(ctx context.Context, cmd *exec.Cmd, cmdName string, timeoutDelay time.Duration) ([]byte, error) {
|
||||||
// Start a timer to print a message if the command takes too long
|
// Use done channel to cleanly exit goroutine when command completes
|
||||||
|
done := make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
select {
|
select {
|
||||||
case <-time.After(timeoutDelay):
|
case <-time.After(timeoutDelay):
|
||||||
fmt.Fprintf(os.Stderr, "⏳ %s is taking longer than expected (possibly waiting for authentication). If this hangs, check for a browser auth prompt or run 'git status' in another terminal.\n", cmdName)
|
fmt.Fprintf(os.Stderr, "⏳ %s is taking longer than expected (possibly waiting for authentication). If this hangs, check for a browser auth prompt or run 'git status' in another terminal.\n", cmdName)
|
||||||
|
case <-done:
|
||||||
|
// Command completed, exit cleanly
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
// Context canceled, don't print message
|
// Context canceled, don't print message
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
output, err := cmd.CombinedOutput()
|
output, err := cmd.CombinedOutput()
|
||||||
|
close(done)
|
||||||
return output, err
|
return output, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -785,17 +785,21 @@ func fetchAndRebaseInWorktree(ctx context.Context, worktreePath, branch, remote
|
|||||||
//
|
//
|
||||||
// Returns: combined output and error from the command
|
// Returns: combined output and error from the command
|
||||||
func runCmdWithTimeoutMessage(ctx context.Context, timeoutMsg string, timeoutDelay time.Duration, cmd *exec.Cmd) ([]byte, error) {
|
func runCmdWithTimeoutMessage(ctx context.Context, timeoutMsg string, timeoutDelay time.Duration, cmd *exec.Cmd) ([]byte, error) {
|
||||||
// Start a timer to print a message if the command takes too long
|
// Use done channel to cleanly exit goroutine when command completes
|
||||||
|
done := make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
select {
|
select {
|
||||||
case <-time.After(timeoutDelay):
|
case <-time.After(timeoutDelay):
|
||||||
fmt.Fprintf(os.Stderr, "⏳ %s\n", timeoutMsg)
|
fmt.Fprintf(os.Stderr, "⏳ %s\n", timeoutMsg)
|
||||||
|
case <-done:
|
||||||
|
// Command completed, exit cleanly
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
// Context canceled, don't print message
|
// Context canceled, don't print message
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
output, err := cmd.CombinedOutput()
|
output, err := cmd.CombinedOutput()
|
||||||
|
close(done)
|
||||||
return output, err
|
return output, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user