Skip to content

Return from hg calls as soon as their output ends - #403

Open
hahn-kev wants to merge 1 commit into
masterfrom
hg-reader-no-poll
Open

hahn-kev wants to merge 1 commit into
masterfrom
hg-reader-no-poll

Conversation

@hahn-kev

@hahn-kev hahn-kev commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

should improve run time for most hg commands and improve CI by around 5min


AI summary

HgProcessOutputReader.Read checked whether hg's output reader threads had finished by sleeping 100 ms between checks. Every hg call therefore took at least ~220 ms, even when hg itself finished in 140–190 ms.

The reader threads now signal a CountdownEvent when their stream closes, and Read waits on it. The wait returns as soon as both streams close. The 100 ms timeout on the wait is kept only to check for cancellation and the inactivity timeout, which behave as before. The event is disposed when Read returns; if Read has already given up (timeout or cancel), the readers ignore the resulting ObjectDisposedException. Waiting on the event also gives the reader threads' Results a memory barrier, which the old polling loop didn't have.

Measured (median of 20 runs, Windows, a small repo):

Command hg.exe directly HgRunner before HgRunner after
version 147 ms 218 ms 146 ms
status 182 ms 220 ms 176 ms
log -r tip 193 ms 220 ms 191 ms
tip 193 ms 219 ms 191 ms

The LibChorus.Tests run makes about 5,500 hg calls, so this should take roughly 4–6 min off its ~26 min on Windows. It also speeds up every hg call during a real Send/Receive.

Test plan

  • HgProcessReaderTests and ProcessStreamTests pass locally (they cover timeout and cancellation), as do HistoryTests
  • Benchmarked HgRunner.Run against launching hg.exe directly (table above)
  • Full CI test run passes; compare the LibChorus test step time with master (~27 min on Windows)

🤖 Generated with Claude Code


This change is Reviewable

HgProcessOutputReader.Read polled for the reader threads every 100 ms,
so every hg call took at least ~220 ms even when hg finished in 140 ms.
The readers now signal a CountdownEvent and Read waits on it, keeping the
100 ms interval only for the cancellation and inactivity-timeout checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@hahn-kev
hahn-kev requested a review from rmunn October 1, 2026 06:15
@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown

Test Results

       8 files  ±0     346 suites  ±0   1h 1m 47s ⏱️ - 11m 27s
1 031 tests ±0     975 ✔️ ±0    56 💤 ±0  0 ❌ ±0 
3 266 runs  ±0  3 143 ✔️ ±0  123 💤 ±0  0 ❌ ±0 

Results for commit b3ca92b. ± Comparison against base commit 116b10b.

@rmunn rmunn left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will definitely be a speed improvement; I had wondered why all calls to hg.exe or chg seemed to take 100ms, and now it's clearer why. This will definitely be an improvement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants