Forward CancellationToken through the build pipeline#284
Conversation
bv subcommands received a CancellationToken but discarded it, so Ctrl+C could not interrupt an in-flight restore/build/test/pack: the spawned dotnet kept running until it finished on its own. Thread the token from each command through BuildPipeline and DotNetService to the process runner. CliWrap kills the dotnet process tree on cancellation; the pipeline stops launching further steps, and Program maps the resulting OperationCanceledException to exit code 130. Closes Tenacom#282 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
@claude please review this PR. |
|
Claude finished @rdeago's task in 2m 10s —— View job PR Review
Overall this is a clean, correct, and complete implementation. The token threads end-to-end with no gaps, and the exit-code mapping is exactly right. A few observations below — none are blockers. Correctness
Minor observations
One thing worth double-checkingThe comment on line 95 ( Summary: no bugs, no style violations, and the token is forwarded correctly through every code path in scope. Ready to merge. |
Console.CancelKeyPress -= OnCancel does not wait for an in-flight handler invocation to return, so a Ctrl-C arriving just before the finally block could call cts.Cancel() after cts.Dispose() had run, throwing ObjectDisposedException on the handler thread. Replace the `using` declaration with explicit disposal in the finally block, guarded by a Lock shared with the handler's Cancel() call. The handler skips cancellation once the source is disposed, so the two can no longer race. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
Thanks for the review! On the one point you flagged as out-of-scope: rather than just softening the comment on
The two cosmetic notes (the @claude please review again. |
|
Claude finished @rdeago's task in 2m 31s —— View job PR Review (follow-up)
The fix is correct. Here's the full reasoning: How the race is closedThe critical invariant is that
Points checked
Comment accuracy ( Nothing to change. The fix is minimal, correct, and well-commented. Ready to merge. |
Summary
bvsubcommands received aCancellationTokenbut discarded it, so Ctrl+C could notinterrupt an in-flight
restore/build/test/pack— the spawneddotnetran tocompletion on its own. This threads the token end-to-end.
BuildPipeline(RunThroughAsync/RunRangeAsync/RunAsync+ step methods) andDotNetService(the five public methods +RunDotNetAsync) now take and forward aCancellationTokento the process runner.RunRangeAsyncstops launching furthersteps once the token is signalled;
CleanAsynchonors it between per-project deletions.dotnetprocess tree (no orphaned children)and throws
OperationCanceledException;Programmaps that to exit code130.DocFxService(in-process DocFX API) andGitService(LibGit2Sharp) spawn no childprocesses, so they're untouched.
Test plan
dotnet bv pack— clean/restore/build/test/pack all green; artifacts produced.inspectcode --severity=WARNING— 0 results.bv buildterminatesdotnetpromptly andbvexits 130(not exercised — interactive; code path + CliWrap contract verified instead).
Closes #282