Skip to content

Commit 545b7de

Browse files
committed
address comments from Richard Murillo
1 parent 545ae4b commit 545b7de

5 files changed

Lines changed: 46 additions & 4 deletions

File tree

content/learning-paths/servers-and-cloud-computing/dotnet-migration-nopcommerce/2-environment-setup.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ docker --version
4040

4141
Expected output: `Arm` (kernel strings may still show architecture-specific values). Ensure the .NET SDK version is 9.0.x.
4242

43+
If you are upgrading from an older .NET version before migrating to Cobalt, you can use [GitHub Copilot modernization for .NET](https://learn.microsoft.com/dotnet/core/porting/github-copilot-app-modernization/overview) to assess the project and guide the upgrade. In Visual Studio Code, open Copilot Chat and use `@modernize-dotnet`; in Visual Studio, use the Modernize action from Solution Explorer.
44+
4345
## PostgreSQL prerequisite for nopCommerce install
4446

4547
nopCommerce defaults to SQL Server, but this learning path uses PostgreSQL for Arm validation. For PostgreSQL installs, `citext` is required before migration/installation. Without it, installer migrations fail with `type "citext" does not exist` (captured in local test artifacts).

content/learning-paths/servers-and-cloud-computing/dotnet-migration-nopcommerce/5-containerization.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,11 @@ dotnet publish src/Presentation/Nop.Web/Nop.Web.csproj \
3535

3636
### 3. .NET SDK multi-arch path
3737

38-
Define multi-arch runtime identifiers in the project file, then publish once.
38+
Define runtime identifiers and multi-arch container runtime identifiers in the project file, then publish once.
3939

4040
```xml
4141
<PropertyGroup>
42+
<RuntimeIdentifiers>linux-x64;linux-arm64</RuntimeIdentifiers>
4243
<ContainerRuntimeIdentifiers>linux-x64;linux-arm64</ContainerRuntimeIdentifiers>
4344
</PropertyGroup>
4445
```
@@ -50,6 +51,16 @@ dotnet publish src/Presentation/Nop.Web/Nop.Web.csproj -c Release /t:PublishCont
5051

5152
This is the scalable path for one image definition across both architectures.
5253

54+
## SDK version guardrail
55+
56+
Before choosing the SDK publish path for multi-architecture images, check the SDK version used by CI and by developer workstations:
57+
58+
```bash
59+
dotnet --version
60+
```
61+
62+
If you cannot use a .NET SDK version that supports multi-RID container publishing, or if SDK publish does not produce the multi-architecture image index you need, use the `docker buildx build --platform linux/amd64,linux/arm64` workflow instead. Multi-RID container publishing starts with .NET SDK versions 8.0.405, 9.0.102, and 9.0.2xx.
63+
5364
## Recommendation
5465

5566
Use SDK publish as the default migration path. Use a Dockerfile workflow for advanced layer control or custom build logic.

content/learning-paths/servers-and-cloud-computing/dotnet-migration-nopcommerce/6-deploy-verify-cobalt.md

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ Treat tuning as an experiment pipeline, not a one-shot tweak. On Arm, apply chan
1212

1313
## Tuned run configuration
1414

15-
Start with a conservative runtime profile that is commonly effective for server workloads.
15+
Start with a conservative runtime profile that is commonly effective for server workloads. Keep these settings outside the application code at first so you can switch profiles without rebuilding.
1616

1717
```bash
18+
export DOTNET_TieredCompilation=1
1819
export DOTNET_TieredPGO=1
1920
export DOTNET_ReadyToRun=1
2021
export DOTNET_gcServer=1
@@ -23,6 +24,26 @@ export DOTNET_EnableDiagnostics=0
2324
export DOTNET_ThreadPool_ForceMinWorkerThreads=2
2425
```
2526

27+
Increase `DOTNET_ThreadPool_ForceMinWorkerThreads` only when traces or load-test data show thread-pool starvation.
28+
29+
### Optional spin-wait experiment for .NET 8, 9, and 10
30+
31+
If the workload burns CPU while waiting for short-lived thread-pool work, test disabling the thread-pool unfair semaphore spin limit:
32+
33+
```bash
34+
export DOTNET_ThreadPool_UnfairSemaphoreSpinLimit=0
35+
```
36+
37+
Treat this as an experiment, not a default. Turning off spin waiting can reduce wasted CPU on small instances or oversubscribed containers, but it can also increase wake-up latency and reduce peak throughput. Validate it separately from the base tuned profile.
38+
39+
### Tiered PGO and ReadyToRun optimize different phases
40+
41+
`DOTNET_TieredPGO=1` and `DOTNET_ReadyToRun=1` are not the same optimization:
42+
43+
- `ReadyToRun` favors startup and early request latency by using precompiled code when it is available.
44+
- `TieredPGO` favors steady-state throughput by letting the JIT recompile hot methods with runtime profile data.
45+
- Test them together and separately if startup latency and warmed throughput both matter.
46+
2647
Run the same endpoint suite used in the baseline:
2748

2849
```bash
@@ -44,6 +65,10 @@ Use these rules before adopting a tuning profile:
4465
- Require improvement in both throughput and p95 latency, not just one.
4566
- Set a minimum practical threshold (for example, >=5% median gain) before rollout.
4667

68+
## Instance-size tradeoffs
69+
70+
Do not assume the same profile wins on every Azure Cobalt VM size. Smaller instances often benefit from lower CPU burn and predictable p95 latency. Larger instances often benefit from higher concurrency, but can expose GC, database, and shared-resource contention. Compare throughput, p95/p99 latency, CPU utilization, and error rate for each instance size before keeping a tuning profile.
71+
4772
## Interpretation
4873

4974
- If only one metric improves while p95 or error rate regresses, do not treat the change as a win.

content/learning-paths/servers-and-cloud-computing/dotnet-migration-nopcommerce/7-arm-mcp-server.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ On this Ubuntu Neoverse (Azure Cobalt) instance:
6565

6666
Typical optimization actions include:
6767

68-
- Runtime settings (`DOTNET_TieredPGO`, `DOTNET_ReadyToRun`, thread pool tuning)
68+
- Runtime settings (`DOTNET_TieredPGO`, `DOTNET_ReadyToRun`, thread pool tuning, and spin-wait experiments)
6969
- Container/runtime configuration cleanup
7070
- Architecture-conditional deployment settings
7171
- Repeated measurement loops with fixed workload parameters and fixed endpoint order

content/learning-paths/servers-and-cloud-computing/dotnet-migration-nopcommerce/_index.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ further_reading:
4343
title: .NET SDK container publish overview
4444
link: https://learn.microsoft.com/dotnet/core/containers/overview
4545
type: documentation
46+
- resource:
47+
title: GitHub Copilot modernization for .NET
48+
link: https://learn.microsoft.com/dotnet/core/porting/github-copilot-app-modernization/overview
49+
type: documentation
4650
- resource:
4751
title: .NET on Arm
4852
link: https://learn.microsoft.com/dotnet/core/install/linux-arm64
@@ -57,4 +61,4 @@ further_reading:
5761
weight: 1 # _index.md always has weight of 1 to order correctly
5862
layout: "learningpathall" # All files under learning paths have this same wrapper
5963
learning_path_main_page: "yes" # This should be surfaced when looking for related content. Only set for _index.md of learning path content.
60-
---
64+
---

0 commit comments

Comments
 (0)