Skip to content

Commit 3dfd293

Browse files
committed
Merge branch 'main' into fix-reexecution-priority-and-streaming-renering
2 parents 79c95e9 + 336519c commit 3dfd293

File tree

196 files changed

+6141
-1355
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

196 files changed

+6141
-1355
lines changed

.azure/pipelines/components-e2e-tests.yml

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,35 @@ jobs:
5858
displayName: Build JS
5959
- script: .dotnet/dotnet build ./src/Components/test/E2ETest -c $(BuildConfiguration) --no-restore
6060
displayName: Build
61-
- script: .dotnet/dotnet test ./src/Components/test/E2ETest -c $(BuildConfiguration) --no-build --filter 'Quarantined!=true|Quarantined=false'
62-
-p:VsTestUseMSBuildOutput=false
63-
--logger:"trx%3BLogFileName=Microsoft.AspNetCore.Components.E2ETests.trx"
64-
--logger:"html%3BLogFileName=Microsoft.AspNetCore.Components.E2ETests.html"
65-
--results-directory $(Build.SourcesDirectory)/artifacts/TestResults/$(BuildConfiguration)/Unquarantined
61+
- script: |
62+
set -o pipefail
63+
64+
.dotnet/dotnet test ./src/Components/test/E2ETest \
65+
-c $(BuildConfiguration) \
66+
--no-build \
67+
--filter 'Quarantined!=true|Quarantined=false' \
68+
-p:VsTestUseMSBuildOutput=false \
69+
--logger:"trx%3BLogFileName=Microsoft.AspNetCore.Components.E2ETests.trx" \
70+
--logger:"html%3BLogFileName=Microsoft.AspNetCore.Components.E2ETests.html" \
71+
--results-directory $(Build.SourcesDirectory)/artifacts/TestResults/$(BuildConfiguration)/Unquarantined \
72+
| tee e2e-test-output.log
73+
74+
if grep -q "No test matches the given testcase filter" e2e-test-output.log
75+
then
76+
echo "##vso[task.logissue type=error] No tests matched the filter."
77+
78+
exit 1
79+
fi
80+
81+
# Check total tests run to detect abnormalities. In case the number of tests changes significantly, we should adjust the threshold.
82+
# Extract total from the summary line "Failed: xx, Passed: yy, Skipped: zz, Total: NNN, Duration: ..."
83+
total=$(sed -nE 's/.*Failed:[[:space:]]*[0-9]+,[[:space:]]*Passed:[[:space:]]*[0-9]+,[[:space:]]*Skipped:[[:space:]]*[0-9]+,[[:space:]]*Total:[[:space:]]*([0-9]+).*/\1/p' e2e-test-output.log)
84+
min_total=1000
85+
if [ -z "$total" ] || [ "$total" -lt "$min_total" ]
86+
then
87+
echo "##vso[task.logissue type=error] Insufficient total test count: $total. We expect at least $min_total tests to run."
88+
exit 1
89+
fi
6690
displayName: Run E2E tests
6791
- script: .dotnet/dotnet test ./src/Components/test/E2ETest -c $(BuildConfiguration) --no-build --filter 'Quarantined=true' -p:RunQuarantinedTests=true
6892
-p:VsTestUseMSBuildOutput=false

.github/workflows/backport.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ permissions:
1414

1515
jobs:
1616
backport:
17-
uses: dotnet/arcade/.github/workflows/backport-base.yml@fdcda9b4919dd16bd2388b5421cc5d55afac0e88 # 2025-01-13
17+
uses: dotnet/arcade/.github/workflows/backport-base.yml@d237be4630776450573bc588eb995bb8f9ebc04f # 2025-01-13
1818
with:
1919
pr_description_template: |
2020
Backport of #%source_pr_number% to %target_branch%

.github/workflows/inter-branch-merge-flow.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ permissions:
1010

1111
jobs:
1212
Merge:
13-
uses: dotnet/arcade/.github/workflows/backport-base.yml@fdcda9b4919dd16bd2388b5421cc5d55afac0e88 # 2024-06-24
13+
uses: dotnet/arcade/.github/workflows/backport-base.yml@d237be4630776450573bc588eb995bb8f9ebc04f # 2024-06-24

eng/Dependencies.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ and are generated based on the last package release.
2929
<LatestPackageReference Include="Microsoft.DotNet.HotReload.Agent.Data" />
3030
<LatestPackageReference Include="Microsoft.Extensions.Caching.Abstractions" />
3131
<LatestPackageReference Include="Microsoft.Extensions.Caching.Memory" />
32+
<LatestPackageReference Include="Microsoft.Extensions.Caching.Hybrid" />
3233
<LatestPackageReference Include="Microsoft.Extensions.Configuration.Abstractions" />
3334
<LatestPackageReference Include="Microsoft.Extensions.Configuration.Binder" />
3435
<LatestPackageReference Include="Microsoft.Extensions.Configuration.CommandLine" />

eng/Version.Details.xml

Lines changed: 185 additions & 181 deletions
Large diffs are not rendered by default.

eng/Versions.props

Lines changed: 91 additions & 90 deletions
Large diffs are not rendered by default.

eng/common/core-templates/job/onelocbuild.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,7 @@ jobs:
8686
isAutoCompletePrSelected: ${{ parameters.AutoCompletePr }}
8787
${{ if eq(parameters.CreatePr, true) }}:
8888
isUseLfLineEndingsSelected: ${{ parameters.UseLfLineEndings }}
89-
${{ if eq(parameters.RepoType, 'gitHub') }}:
90-
isShouldReusePrSelected: ${{ parameters.ReusePr }}
89+
isShouldReusePrSelected: ${{ parameters.ReusePr }}
9190
packageSourceAuth: patAuth
9291
patVariable: ${{ parameters.CeapexPat }}
9392
${{ if eq(parameters.RepoType, 'gitHub') }}:
@@ -118,4 +117,4 @@ jobs:
118117
pathToPublish: '$(Build.SourcesDirectory)/eng/Localize/'
119118
publishLocation: Container
120119
artifactName: Loc
121-
condition: ${{ parameters.condition }}
120+
condition: ${{ parameters.condition }}

global.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
{
22
"sdk": {
3-
"version": "10.0.100-preview.6.25272.112"
3+
"version": "10.0.100-preview.6.25302.104"
44
},
55
"tools": {
6-
"dotnet": "10.0.100-preview.6.25272.112",
6+
"dotnet": "10.0.100-preview.6.25302.104",
77
"runtimes": {
88
"dotnet/x86": [
99
"$(MicrosoftInternalRuntimeAspNetCoreTransportVersion)"
@@ -27,9 +27,9 @@
2727
"jdk": "latest"
2828
},
2929
"msbuild-sdks": {
30-
"Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25303.102",
31-
"Microsoft.DotNet.Helix.Sdk": "10.0.0-beta.25303.102",
32-
"Microsoft.DotNet.SharedFramework.Sdk": "10.0.0-beta.25303.102",
30+
"Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25311.102",
31+
"Microsoft.DotNet.Helix.Sdk": "10.0.0-beta.25311.102",
32+
"Microsoft.DotNet.SharedFramework.Sdk": "10.0.0-beta.25311.102",
3333
"Microsoft.Build.NoTargets": "3.7.0",
3434
"Microsoft.Build.Traversal": "3.4.0"
3535
}

src/Components/Components/src/ComponentsActivitySource.cs

Lines changed: 66 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System.Diagnostics;
5+
using Microsoft.AspNetCore.Components.Infrastructure;
56

67
namespace Microsoft.AspNetCore.Components;
78

@@ -11,115 +12,66 @@ namespace Microsoft.AspNetCore.Components;
1112
internal class ComponentsActivitySource
1213
{
1314
internal const string Name = "Microsoft.AspNetCore.Components";
14-
internal const string OnCircuitName = $"{Name}.CircuitStart";
1515
internal const string OnRouteName = $"{Name}.RouteChange";
1616
internal const string OnEventName = $"{Name}.HandleEvent";
1717

18-
private ActivityContext _httpContext;
19-
private ActivityContext _circuitContext;
20-
private string? _circuitId;
21-
private ActivityContext _routeContext;
22-
2318
private ActivitySource ActivitySource { get; } = new ActivitySource(Name);
19+
private ComponentsActivityLinkStore? _componentsActivityLinkStore;
2420

25-
public static ActivityContext CaptureHttpContext()
21+
public void Init(ComponentsActivityLinkStore store)
2622
{
27-
var parentActivity = Activity.Current;
28-
if (parentActivity is not null && parentActivity.OperationName == "Microsoft.AspNetCore.Hosting.HttpRequestIn" && parentActivity.Recorded)
29-
{
30-
return parentActivity.Context;
31-
}
32-
return default;
23+
_componentsActivityLinkStore = store;
3324
}
3425

35-
public Activity? StartCircuitActivity(string circuitId, ActivityContext httpContext)
26+
public ComponentsActivityHandle StartRouteActivity(string componentType, string route)
3627
{
37-
_circuitId = circuitId;
38-
39-
var activity = ActivitySource.CreateActivity(OnCircuitName, ActivityKind.Internal, parentId: null, null, null);
28+
var activity = ActivitySource.CreateActivity(OnRouteName, ActivityKind.Internal, parentId: null, null, null);
4029
if (activity is not null)
4130
{
42-
if (activity.IsAllDataRequested)
43-
{
44-
if (_circuitId != null)
45-
{
46-
activity.SetTag("aspnetcore.components.circuit.id", _circuitId);
47-
}
48-
if (httpContext != default)
49-
{
50-
activity.AddLink(new ActivityLink(httpContext));
51-
}
52-
}
53-
activity.DisplayName = $"Circuit {circuitId ?? ""}";
31+
var httpActivity = Activity.Current;
32+
activity.DisplayName = $"Route {route ?? "[unknown path]"} -> {componentType ?? "[unknown component]"}";
33+
Activity.Current = null; // do not inherit the parent activity
5434
activity.Start();
55-
_circuitContext = activity.Context;
56-
}
57-
return activity;
58-
}
5935

60-
public void FailCircuitActivity(Activity? activity, Exception ex)
61-
{
62-
_circuitContext = default;
63-
if (activity != null && !activity.IsStopped)
64-
{
65-
activity.SetTag("error.type", ex.GetType().FullName);
66-
activity.SetStatus(ActivityStatusCode.Error);
67-
activity.Stop();
68-
}
69-
}
70-
71-
public Activity? StartRouteActivity(string componentType, string route)
72-
{
73-
if (_httpContext == default)
74-
{
75-
_httpContext = CaptureHttpContext();
76-
}
77-
78-
var activity = ActivitySource.CreateActivity(OnRouteName, ActivityKind.Internal, parentId: null, null, null);
79-
if (activity is not null)
80-
{
8136
if (activity.IsAllDataRequested)
8237
{
83-
if (_circuitId != null)
84-
{
85-
activity.SetTag("aspnetcore.components.circuit.id", _circuitId);
86-
}
8738
if (componentType != null)
8839
{
8940
activity.SetTag("aspnetcore.components.type", componentType);
9041
}
9142
if (route != null)
9243
{
9344
activity.SetTag("aspnetcore.components.route", route);
94-
}
95-
if (_httpContext != default)
96-
{
97-
activity.AddLink(new ActivityLink(_httpContext));
98-
}
99-
if (_circuitContext != default)
100-
{
101-
activity.AddLink(new ActivityLink(_circuitContext));
45+
46+
// store self link
47+
_componentsActivityLinkStore!.SetActivityContext(ComponentsActivityLinkStore.Route, activity.Context,
48+
new KeyValuePair<string, object?>("aspnetcore.components.route", route));
10249
}
10350
}
10451

105-
activity.DisplayName = $"Route {route ?? "[unknown path]"} -> {componentType ?? "[unknown component]"}";
106-
activity.Start();
107-
_routeContext = activity.Context;
52+
return new ComponentsActivityHandle { Activity = activity, Previous = httpActivity };
10853
}
109-
return activity;
54+
return default;
55+
}
56+
57+
public void StopRouteActivity(ComponentsActivityHandle activityHandle, Exception? ex)
58+
{
59+
StopComponentActivity(ComponentsActivityLinkStore.Route, activityHandle, ex);
11060
}
11161

112-
public Activity? StartEventActivity(string? componentType, string? methodName, string? attributeName)
62+
public ComponentsActivityHandle StartEventActivity(string? componentType, string? methodName, string? attributeName)
11363
{
11464
var activity = ActivitySource.CreateActivity(OnEventName, ActivityKind.Internal, parentId: null, null, null);
65+
11566
if (activity is not null)
11667
{
68+
var previousActivity = Activity.Current;
69+
activity.DisplayName = $"Event {attributeName ?? "[unknown attribute]"} -> {componentType ?? "[unknown component]"}.{methodName ?? "[unknown method]"}";
70+
Activity.Current = null; // do not inherit the parent activity
71+
activity.Start();
72+
11773
if (activity.IsAllDataRequested)
11874
{
119-
if (_circuitId != null)
120-
{
121-
activity.SetTag("aspnetcore.components.circuit.id", _circuitId);
122-
}
12375
if (componentType != null)
12476
{
12577
activity.SetTag("aspnetcore.components.type", componentType);
@@ -132,46 +84,60 @@ public void FailCircuitActivity(Activity? activity, Exception ex)
13284
{
13385
activity.SetTag("aspnetcore.components.attribute.name", attributeName);
13486
}
135-
if (_httpContext != default)
136-
{
137-
activity.AddLink(new ActivityLink(_httpContext));
138-
}
139-
if (_circuitContext != default)
140-
{
141-
activity.AddLink(new ActivityLink(_circuitContext));
142-
}
143-
if (_routeContext != default)
144-
{
145-
activity.AddLink(new ActivityLink(_routeContext));
146-
}
14787
}
14888

149-
activity.DisplayName = $"Event {attributeName ?? "[unknown attribute]"} -> {componentType ?? "[unknown component]"}.{methodName ?? "[unknown method]"}";
150-
activity.Start();
89+
return new ComponentsActivityHandle { Activity = activity, Previous = previousActivity };
15190
}
152-
return activity;
91+
return default;
15392
}
15493

155-
public static void FailEventActivity(Activity? activity, Exception ex)
94+
public void StopEventActivity(ComponentsActivityHandle activityHandle, Exception? ex)
15695
{
157-
if (activity != null && !activity.IsStopped)
158-
{
159-
activity.SetTag("error.type", ex.GetType().FullName);
160-
activity.SetStatus(ActivityStatusCode.Error);
161-
activity.Stop();
162-
}
96+
StopComponentActivity(ComponentsActivityLinkStore.Event, activityHandle, ex);
16397
}
16498

165-
public static async Task CaptureEventStopAsync(Task task, Activity? activity)
99+
public async Task CaptureEventStopAsync(Task task, ComponentsActivityHandle activityHandle)
166100
{
167101
try
168102
{
169103
await task;
170-
activity?.Stop();
104+
StopEventActivity(activityHandle, null);
171105
}
172106
catch (Exception ex)
173107
{
174-
FailEventActivity(activity, ex);
108+
StopEventActivity(activityHandle, ex);
175109
}
176110
}
111+
112+
private void StopComponentActivity(string category, ComponentsActivityHandle activityHandle, Exception? ex)
113+
{
114+
var activity = activityHandle.Activity;
115+
if (activity != null && !activity.IsStopped)
116+
{
117+
if (ex != null)
118+
{
119+
activity.SetTag("error.type", ex.GetType().FullName);
120+
activity.SetStatus(ActivityStatusCode.Error);
121+
}
122+
if (activity.IsAllDataRequested)
123+
{
124+
_componentsActivityLinkStore!.AddActivityContexts(category, activity);
125+
}
126+
activity.Stop();
127+
128+
if (Activity.Current == null && activityHandle.Previous != null && !activityHandle.Previous.IsStopped)
129+
{
130+
Activity.Current = activityHandle.Previous;
131+
}
132+
}
133+
}
134+
}
135+
136+
/// <summary>
137+
/// Named tuple for restoring the previous activity after stopping the current one.
138+
/// </summary>
139+
internal struct ComponentsActivityHandle
140+
{
141+
public Activity? Previous;
142+
public Activity? Activity;
177143
}

src/Components/Components/src/Microsoft.AspNetCore.Components.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
<Compile Include="$(SharedSourceRoot)Debugger\DictionaryDebugView.cs" LinkBase="Shared" />
2525
<Compile Include="$(SharedSourceRoot)UrlDecoder\UrlDecoder.cs" LinkBase="Shared" />
2626
<Compile Include="$(SharedSourceRoot)Metrics\MetricsConstants.cs" LinkBase="Shared" />
27+
<Compile Include="$(SharedSourceRoot)Components\ComponentsActivityLinkStore.cs" LinkBase="Shared" />
2728
</ItemGroup>
2829

2930
<Import Project="Microsoft.AspNetCore.Components.Routing.targets" />
@@ -79,7 +80,6 @@
7980

8081
<ItemGroup>
8182
<InternalsVisibleTo Include="Microsoft.AspNetCore.Components.Web" />
82-
<InternalsVisibleTo Include="Microsoft.AspNetCore.Components.Server" />
8383
<InternalsVisibleTo Include="Microsoft.AspNetCore.Blazor.Build.Tests" />
8484
<InternalsVisibleTo Include="Microsoft.AspNetCore.Components.Authorization.Tests" />
8585
<InternalsVisibleTo Include="Microsoft.AspNetCore.Components.Forms.Tests" />

0 commit comments

Comments
 (0)