Job Monitor: cancel in-flight Helix jobs on external cancellation (CTRL+C / SIGTERM)#16877
Open
Copilot wants to merge 3 commits into
Open
Job Monitor: cancel in-flight Helix jobs on external cancellation (CTRL+C / SIGTERM)#16877Copilot wants to merge 3 commits into
Copilot wants to merge 3 commits into
Conversation
…bs on CTRL+C/SIGTERM When AzDO times out a pipeline job, it sends CTRL+C (Windows) or SIGTERM (Linux) to the process. The previous Program.cs called runner.RunAsync() which only handled an internal timeout, not external cancellation signals. This change: - Registers Console.CancelKeyPress handler for CTRL+C on all platforms - Registers PosixSignalRegistration for SIGTERM on non-Windows platforms - Creates a linked CancellationTokenSource combining signals + timeout - Calls runner.RunAsync(linkedCts.Token) so the existing cancellation handler (which calls CancelInFlightHelixJobsAsync) is properly triggered - Removes the now-unused RunAsync() parameterless overload from JobMonitorRunner Agent-Logs-Url: https://github.com/dotnet/arcade/sessions/223cb56d-44f3-45d4-a0f0-13dc2b244f5a Co-authored-by: mmitche <8725170+mmitche@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Fix job monitor to handle cancellation of in-progress jobs
Job Monitor: cancel in-flight Helix jobs on external cancellation (CTRL+C / SIGTERM)
May 23, 2026
premun
previously approved these changes
May 25, 2026
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates the Helix Job Monitor tool so that external pipeline cancellations (CTRL+C on Windows, SIGTERM on Unix) trigger a graceful shutdown path that can cancel in-flight Helix jobs before the process exits.
Changes:
- Register CTRL+C and SIGTERM handlers in
Program.cs, and link a signal-drivenCancellationTokenSourcewith the existingMaximumWaitMinutestimeout into a single token passed to the runner. - Remove the parameterless
JobMonitorRunner.RunAsync()overload now that timeout ownership moves toProgram.cs.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/Microsoft.DotNet.Helix/JobMonitor/Program.cs | Adds external signal handling and links it with the existing timeout to drive graceful cancellation. |
| src/Microsoft.DotNet.Helix/JobMonitor/JobMonitorRunner.cs | Removes the unused parameterless RunAsync() overload. |
premun
approved these changes
May 25, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When AzDO times out a pipeline job, it sends CTRL+C (Windows) or SIGTERM (Linux) to the process.
Program.cspreviously calledrunner.RunAsync()which only set up an internal timeout-based CTS — external signals were never intercepted, so the process was killed before the existingCancelInFlightHelixJobsAsynclogic could run.Changes
Program.cs: Register signal handlers that cancel a sharedCancellationTokenSource:Console.CancelKeyPress(CTRL+C, all platforms) — setse.Cancel = trueto suppress immediate terminationPosixSignalRegistration.Create(PosixSignal.SIGTERM, ...)(Unix only) — setsctx.Cancel = trueto suppress default terminationMaximumWaitMinutes) into a single token passed torunner.RunAsync(linkedCts.Token)JobMonitorRunner.cs: Remove the now-unusedRunAsync()parameterless overload (timeout is owned byProgram.cs)The existing
catch (OperationCanceledException)handler inRunCoreAsync— which already callsCancelInFlightHelixJobsAsyncwith a 30-second bounded window — now fires correctly for both external signals and internal timeouts.To double check: