JobMonitor: Preserve DockerTag/QueueAlias when resubmitting work items - #16963
Merged
Conversation
When the JobMonitor resubmitted failed Helix work items, it built the JobCreationRequest using only the resolved QueueId from Job.DetailsAsync (Docker tag and queue alias stripped), so a work item that originally ran inside a Docker container was re-run on the bare host queue. Reconstruct the original target queue from the `operatingSystem` job property (which the Helix SDK stamps verbatim with $(HelixTargetQueue), in `(alias)queueId@dockerTag` form) and parse it with the same logic the fresh submission path uses (JobDefinition.ParseQueueId), setting QueueId, DockerTag and QueueAlias consistently. Falls back to the resolved QueueId with no Docker tag/alias when the property is absent or unparseable. Fixes dotnet#16961 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes a JobMonitor resubmission fidelity issue where resubmitted Helix work items could lose DockerTag/QueueAlias (causing reruns to execute on the bare host queue instead of the intended Docker-backed environment). It reconstructs the original target queue from the job’s operatingSystem property (stamped by the Helix SDK) so resubmissions match the fresh-submission path.
Changes:
- Update
HelixService.ResubmitWorkItemsAsyncto parse the original target queue from theoperatingSystemproperty and setQueueId,DockerTag, andQueueAliason the resubmittedJobCreationRequest, with a safe fallback to the resolvedQueueIdwhen missing/unparseable. - Add unit tests covering alias+docker, docker-only, non-docker, and unparseable
operatingSystemscenarios. - Extend existing resubmission metadata test assertions to validate
DockerTag/QueueAliasdefault behavior when the property is absent.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/Microsoft.DotNet.Helix/JobMonitor/Services/HelixService.cs | Reconstructs and applies QueueId/DockerTag/QueueAlias for resubmitted jobs by parsing the operatingSystem property (mirroring JobSender behavior), with fallback to prior behavior. |
| src/Microsoft.DotNet.Helix/Sdk.Tests/Microsoft.DotNet.Helix.Sdk.Tests/HelixServiceTests.cs | Adds/updates tests to ensure resubmission preserves Docker/alias info (and falls back correctly) based on the operatingSystem property. |
…eueSpec Extract the Docker tag / queue alias recovery into a single replaceable method and link it to the tracking issue (dotnet#16964) so it can be swapped for direct JobDetails.DockerTag/QueueAlias reads once the Helix details API exposes them (dotnet-helix-service PR 61770). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
premun
approved these changes
Jun 4, 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.
Summary
Fixes #16961.
When the
JobMonitorresubmits failed Helix work items, it builds theJobCreationRequestusing only the resolvedQueueIdfromJob.DetailsAsync(which has the Docker tag and queue alias stripped). As a result, a work item that originally ran inside a Docker container was re-run on the bare host queue — the wrong execution environment.Fix
The Helix SDK MSBuild targets stamp the original target queue string verbatim onto the job''s
operatingSystemproperty (HelixProperties Include="operatingSystem" Value="$(HelixTargetQueue)"inMicrosoft.DotNet.Helix.Sdk.MonoQueue.targets), in the(alias)queueId@dockerTagform. This is the same string the fresh submission path parses.HelixService.ResubmitWorkItemsAsyncnow:operatingSystemproperty and parses it with the same logic the fresh submission path uses (JobDefinition.ParseQueueId), settingQueueId,DockerTag, andQueueAliasconsistently — matching what a fresh Helix SDK submission would send.QueueIdwith no Docker tag/alias when the property is absent or unparseable (preserving prior behavior).This was validated to be the correct source of truth:
Job.DetailsAsyncdoes not exposeDockerTag/QueueAlias, but theoperatingSystemproperty is an exact copy of the originalTargetQueue.Tests
Added unit tests in
HelixServiceTestscovering:QueueId,QueueAlias,DockerTag.QueueIdandDockerTag.QueueId/QueueAlias, emptyDockerTag(mirrors fresh submission).operatingSystem→ falls back to resolvedQueueIdwith null Docker tag/alias.All 126 tests in
Microsoft.DotNet.Helix.Sdk.Testspass.Notes
ResultContainerPrefix(also not copied on resubmission) is intentionally left out of scope per discussion on #16907 — it does not affect queue/Docker selection.