fix(sync): keep the live progress counters correct and race-free
Two defects in the in-place progress line introduced with the reporting work: - started() only ran for repositories that actually synced, but finished() decrements for every repository that records a result. Any repository skipped by the eligibility or pre-sync checks therefore decremented a counter it had never incremented, so the running "active" count went negative and was displayed as such. Count a repository as active before the skip checks can exit. - clear() mutates the line width but ran under outputMu, while draw() mutates the same field under the progress mutex. With parallel jobs one worker could erase the line while another repainted it. Route clear() through the same lock, keeping outputMu around the surrounding writes. Verified by reverting the first fix and watching the new test report "active = -3". 🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com>
This commit is contained in:
@@ -484,6 +484,10 @@ func syncSelectedWithProgress(root string, repos, workspaceRepos []repo, jobs in
|
||||
defer wg.Done()
|
||||
for next := range work {
|
||||
r := next.repo
|
||||
// Counted active before any skip path can record: finished()
|
||||
// decrements again, so an early exit that skipped started()
|
||||
// would drive the active count negative.
|
||||
live.update(func() { live.started(); live.draw() })
|
||||
if !r.Eligible {
|
||||
record(next.index, syncResult{Path: r.RelativePath, Skipped: true, Message: r.BlockReason})
|
||||
continue
|
||||
@@ -503,18 +507,17 @@ func syncSelectedWithProgress(root string, repos, workspaceRepos []repo, jobs in
|
||||
}
|
||||
if !quiet {
|
||||
outputMu.Lock()
|
||||
live.clear()
|
||||
live.update(func() { live.clear() })
|
||||
fmt.Fprintf(stdout, "\nSTART %s (%s)\n", r.RelativePath, r.Branch)
|
||||
outputMu.Unlock()
|
||||
}
|
||||
live.update(func() { live.started(); live.draw() })
|
||||
started := time.Now()
|
||||
report, err := syncRepositoryWith(r.Path, timeout, len(fresh.Dirty) > 0, fresh.NestedRepoEntries, syncOptions{CreateMissing: createMissing})
|
||||
message := report.Message
|
||||
duration := time.Since(started).Round(time.Millisecond).String()
|
||||
if !quiet {
|
||||
outputMu.Lock()
|
||||
live.clear()
|
||||
live.update(func() { live.clear() })
|
||||
state := "DONE"
|
||||
if err != nil {
|
||||
state = "FAIL"
|
||||
|
||||
Reference in New Issue
Block a user