Skip to content

Don't disable the MSBuild server for /mt builds when node reuse is off - #14248

Merged
AR-May merged 3 commits into
dotnet:mainfrom
AR-May:fix-nodereuse-for-mt-2
Jul 3, 2026
Merged

AR-May merged 3 commits into
dotnet:mainfrom
AR-May:fix-nodereuse-for-mt-2

Conversation

@AR-May

@AR-May AR-May commented Jul 2, 2026

Copy link
Copy Markdown
Member

Fixes #14157

Context

When node reuse is disabled (-nr:false), MSBuild refused to use the server node. For a multithreaded ( /mt ) build that's a problem: the server is the only way to get Server GC, which  /mt  builds depend on for performance reasons.

Changes Made

Decouple "may we use the server for this build?" from "may the server stay resident afterward?":

  •  /mt  now uses the server even when node reuse is disabled, purely to obtain Server GC.
  • To honor the no-reuse intent, a new  shutdownServerAfterBuild flag tears the server down immediately after the build completes, so it doesn't persist and each build gets a fresh process.
  • Node reuse being off still disqualifies the server for non- /mt  builds (unchanged behavior).

Testing

Added a unit test.

Notes

Previous attempt: #14161. It tries to shut down the server after the build by issuing a shutdown command. However, previous implementation does not guarantee that the server will not accept another client's request in the meantime and subsequently fail to shut down. Another option would be to re-parse the command line and identify cases where a server shutdown is required, but I would prefer the initial parsing to remain the single source of truth and avoid re-parsing. Client and server are the same handshake-gated MSBuild version, so there's no cross-version serialization concern over the communication protocol.

Copilot AI review requested due to automatic review settings July 2, 2026 09:40
@AR-May
AR-May temporarily deployed to copilot-pat-pool July 2, 2026 09:40 — with GitHub Actions Inactive
@AR-May
AR-May temporarily deployed to copilot-pat-pool July 2, 2026 09:41 — with GitHub Actions Inactive
@AR-May
AR-May temporarily deployed to copilot-pat-pool July 2, 2026 09:42 — with GitHub Actions Inactive
@AR-May
AR-May marked this pull request as draft July 2, 2026 09:47

Copilot AI 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.

Pull request overview

This PR adjusts MSBuild Server routing so /mt builds can still run on the MSBuild Server even when node reuse is disabled (-nr:false), preserving the performance benefit of Server GC while honoring the “no reuse” intent by shutting the server down immediately after the build.

Changes:

  • Decouples “can host build on server” from “can keep server resident,” allowing /mt + -nr:false to use the server but request post-build teardown.
  • Plumbs a new shutdownServerAfterBuild/ShutdownAfterBuild flag from CLI parsing → client → IPC packet → server shutdown behavior.
  • Adds unit test coverage for the new packet field and an end-to-end test for /mt + -nr:false.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/MSBuild/XMake.cs Computes shutdownServerAfterBuild during the authoritative command-line parse and passes it to the server client path.
src/MSBuild/MSBuildClientApp.cs Extends the server client execution entrypoints to pass the shutdown-after-build intent through.
src/Build/BackEnd/Client/MSBuildClient.cs Stores and sends shutdown intent on ServerNodeBuildCommand.
src/Build/BackEnd/Node/ServerNodeBuildCommand.cs Adds ShutdownAfterBuild field to the server build-command packet and serializes it.
src/Build/BackEnd/Node/OutOfProcServerNode.cs Honors ShutdownAfterBuild by exiting after the build instead of returning to reuse mode.
src/MSBuild.UnitTests/MSBuildServer_Tests.cs Adds E2E test that /mt -nr:false uses the server but does not leave it resident.
src/Build.UnitTests/BackEnd/ServerNodeBuildCommand_Tests.cs Adds round-trip serialization test for the new packet field.
documentation/MSBuild-Server.md Documents server lifetime behavior when node reuse is disabled, including the /mt exception.

Comment thread src/MSBuild.UnitTests/MSBuildServer_Tests.cs Outdated
Comment thread src/Build.UnitTests/BackEnd/ServerNodeBuildCommand_Tests.cs
Comment thread documentation/MSBuild-Server.md
@AR-May
AR-May temporarily deployed to copilot-pat-pool July 2, 2026 10:00 — with GitHub Actions Inactive
@AR-May
AR-May marked this pull request as ready for review July 2, 2026 10:13
@AR-May
AR-May merged commit 270af2f into dotnet:main Jul 3, 2026
14 checks passed
JanProvaznik added a commit to JanProvaznik/msbuild that referenced this pull request Jul 8, 2026
Resolves conflicts with dotnet#14248 ("Don't disable the MSBuild server for /mt
builds when node reuse is off"), which introduced the short-lived server
(a /mt build with node reuse off uses the server for Server GC but tears it
down after the build via ServerNodeBuildCommand.ShutdownAfterBuild).

- CanRunServerBasedOnCommandLineSwitches: integrate dotnet#14248's shutdownServerAfterBuild
  and the new node-reuse gate (nodeReuseDisqualifies = !nodeReuse && !multiThreaded)
  with my serverDisabledReason/reasonCode outputs. The node-reuse-disabled reason now
  only fires for non-/mt builds (a /mt build uses a short-lived server instead).
- MSBuildServerLifecycleEventArgs gains a ShortLived flag (serialized in the v27 record
  and node packets). XMake sets it for a spawned server that will shut down afterward,
  and logs a distinct "spawned (short-lived)" message. The flag is surfaced from
  OutOfProcServerNode.CurrentBuildShutsDownServerNode (additive; the public BuildCallback
  delegate is left unchanged to avoid an API break).
- New MSBuildServerNodeSpawnedShortLived resource (+ xlf); docs updated.
- Tests: round-trip covers ShortLived; new e2e ServerShortLivedForMultithreadedWhenNodeReuseOff.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions github-actions Bot mentioned this pull request Jul 30, 2026
WarperSan pushed a commit to WarperSan/ThunderPipe that referenced this pull request Sep 17, 2026
Updated
[Microsoft.Build.Utilities.Core](https://github.com/dotnet/msbuild) from
18.9.6 to 18.10.1.

<details>
<summary>Release notes</summary>

_Sourced from [Microsoft.Build.Utilities.Core's
releases](https://github.com/dotnet/msbuild/releases)._

## 18.10.1

## What's Changed
* [vs16.11] Update dependencies from dotnet/arcade by
@​dotnet-maestro[bot] in dotnet/msbuild#13103
* [vs17.12] Update dependencies from dotnet/arcade by
@​dotnet-maestro[bot] in dotnet/msbuild#13796
* [vs17.8] Update dependencies from dotnet/arcade by
@​dotnet-maestro[bot] in dotnet/msbuild#13902
* [vs17.11] Update dependencies from dotnet/arcade by
@​dotnet-maestro[bot] in dotnet/msbuild#13903
* [vs17.12] Update dependencies from dotnet/arcade by
@​dotnet-maestro[bot] in dotnet/msbuild#13909
* [vs17.12] Update dependencies from dotnet/arcade by
@​dotnet-maestro[bot] in dotnet/msbuild#13986
* Add vs18.9 to merge-flow config; retire vs18.3 by @​JanProvaznik in
dotnet/msbuild#14214
* Bump labeler-cache-retention to use issue-labeler v2.1.0 by
@​jeffhandley in dotnet/msbuild#14171
* Bump main to 18.10.0 after vs18.9 snap by @​JanProvaznik in
dotnet/msbuild#14216
* Improve release skill: Phase 2 DARC rules, VMR backflow, deterministic
baseline by @​JanProvaznik in
dotnet/msbuild#14220
* Determinize release: hardcode OptProf baseline + Phase 3.2 baseline
resolver by @​JanProvaznik in
dotnet/msbuild#14222
* Serialize BuildRequestConfiguration.RequestedTargets to fix solution
metaproject MSB4057 in parallel builds by @​ViktorHofer in
dotnet/msbuild#14223
* [main] Update dependencies from nuget/nuget.client by
@​dotnet-maestro[bot] in dotnet/msbuild#14203
* Core support for AbsolutePath/FileInfo/DirectoryInfo and ITaskItem<T>
as task parameters by @​baronfel in
dotnet/msbuild#13971
* [main] Update dependencies from dotnet/roslyn by @​dotnet-maestro[bot]
in dotnet/msbuild#14206
* Fix existence cache kind poisoning by @​AlesProkop in
dotnet/msbuild#14249
* [main] Source code updates from dotnet/dotnet by @​dotnet-maestro[bot]
in dotnet/msbuild#14226
* Don't disable the MSBuild server for /mt builds when node reuse is off
by @​AR-May in dotnet/msbuild#14248
* Enhance expert reviewer guidelines with additional checks. by @​AR-May
in dotnet/msbuild#14255
* [main] Source code updates from dotnet/dotnet by @​dotnet-maestro[bot]
in dotnet/msbuild#14253
* [main] Update dependencies from dotnet/roslyn by @​dotnet-maestro[bot]
in dotnet/msbuild#14268
* [main] Update dependencies from nuget/nuget.client by
@​dotnet-maestro[bot] in dotnet/msbuild#14267
* Bump github/gh-aw-actions/setup from 0.81.6 to 0.82.2 by
@​dependabot[bot] in dotnet/msbuild#14266
* Avoid boxing the struct enumerator in
PropertyDictionary<T>.GetEnumerator() by @​nareshjo in
dotnet/msbuild#14272
* Refresh copy marker when implementation output changes by @​AlesProkop
in dotnet/msbuild#14231
* Send task-host build process environment as delta by @​OvesN in
dotnet/msbuild#14126
* Add regression coverage for metadata newline preservation by
@​VolPlita in dotnet/msbuild#14261
* Fix EmbedInBinlog items with relative paths from child projects by
@​huulinhnguyen-dev in dotnet/msbuild#13990
* Stop requiring VersionPrefix updates in servicing - insert prerelease
versions to VS by @​ViktorHofer in
dotnet/msbuild#14277
* Fix WriteLinesToFile rewriting unchanged file when custom encoding is
used by @​huulinhnguyen-dev in
dotnet/msbuild#14146
* Enable trim/AOT analyzers for Microsoft.Build and clean up annotations
by @​JeremyKuhne in dotnet/msbuild#14064
* [automated] Merge branch 'vs18.9' => 'main' by @​github-actions[bot]
in dotnet/msbuild#14291
* Fix MicroBuild plugin feed URL to use allowed pkgs.dev.azure.com
format by @​AlesProkop in dotnet/msbuild#14295
* Pass ExcludeRestorePackageImports during restore to avoid redundant
evaluations by @​ViktorHofer with @​Copilot in
dotnet/msbuild#14274
* [vs18.7] Update dependencies from dotnet/arcade by
@​dotnet-maestro[bot] in dotnet/msbuild#13988
* Adopt Clever Test Selection (CTS) as parallel, non-blocking PR
pipeline by @​jankratochvilcz in
dotnet/msbuild#14212
* Harden exceptions when connecting to server by @​JanProvaznik in
dotnet/msbuild#14292
* Update MicrosoftBuildVersion in analyzer template by
@​github-actions[bot] in dotnet/msbuild#13886
* Fix MSBuild Server client dropping build result under WaitAny race
(#​14172) by @​JanProvaznik in
dotnet/msbuild#14251
* Partially revert #​13660: remove NuGet RestoreTask transient TaskHost
workaround by @​JanProvaznik in
dotnet/msbuild#14297
* Disable daily AI credits guardrail for Expert Code Review workflow by
@​JanProvaznik with @​Copilot in
dotnet/msbuild#14314
* Localized file check-in by OneLocBuild Task: Build definition ID 9434:
Build ID 14614733 by @​dotnet-bot in
dotnet/msbuild#14246
* Add opt-in partial (stop-after-pass) project evaluation by
@​ViktorHofer in dotnet/msbuild#14290
* Use partial evaluation for -getProperty/-getItem without a target by
@​ViktorHofer in dotnet/msbuild#14296
* [main] Source code updates from dotnet/dotnet by @​dotnet-maestro[bot]
in dotnet/msbuild#14324
* [main] Update dependencies from dotnet/roslyn by @​dotnet-maestro[bot]
in dotnet/msbuild#14333
* [main] Update dependencies from nuget/nuget.client by
@​dotnet-maestro[bot] in dotnet/msbuild#14330
* Bump github/gh-aw-actions/setup from 0.82.2 to 0.82.8 by
@​dependabot[bot] in dotnet/msbuild#14328
* Restrict partial evaluation to ProjectInstance by @​ViktorHofer in
dotnet/msbuild#14340
 ... (truncated)

Commits viewable in [compare
view](dotnet/msbuild@v18.9.6...v18.10.1).
</details>

[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=Microsoft.Build.Utilities.Core&package-manager=nuget&previous-version=18.9.6&new-version=18.10.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
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.

MT mode should still use MSBuild Server even when node reuse is disabled consider Server GC for main -mt process even if we're not in server mode

4 participants