Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/aspnetcore.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Halter <halter73@gmail.com>2022-09-03 05:54:24 +0300
committerStephen Halter <halter73@gmail.com>2022-09-03 06:51:15 +0300
commitbe482641d796d152257135c2fe7b32ff6b5d5f3c (patch)
tree78df9ca3d975ef6de73710e4eb04377a100223e0
parentcb2b64804da8e838e2990a98a16d5b80d522ff5b (diff)
Don't cache Endpoints if a source throwshalter73/43693
-rw-r--r--src/Http/Routing/src/CompositeEndpointDataSource.cs14
-rw-r--r--src/Http/Routing/test/UnitTests/CompositeEndpointDataSourceTest.cs36
2 files changed, 45 insertions, 5 deletions
diff --git a/src/Http/Routing/src/CompositeEndpointDataSource.cs b/src/Http/Routing/src/CompositeEndpointDataSource.cs
index bb4250d26b..8c1ea4c586 100644
--- a/src/Http/Routing/src/CompositeEndpointDataSource.cs
+++ b/src/Http/Routing/src/CompositeEndpointDataSource.cs
@@ -242,8 +242,7 @@ public sealed class CompositeEndpointDataSource : EndpointDataSource, IDisposabl
[MemberNotNull(nameof(_consumerChangeToken))]
private void CreateChangeTokenUnsynchronized(bool collectionChanged)
{
- _cts = new CancellationTokenSource();
- _consumerChangeToken = new CancellationChangeToken(_cts.Token);
+ var cts = new CancellationTokenSource();
if (collectionChanged)
{
@@ -255,17 +254,24 @@ public sealed class CompositeEndpointDataSource : EndpointDataSource, IDisposabl
() => HandleChange(collectionChanged: false)));
}
}
+
+ _cts = cts;
+ _consumerChangeToken = new CancellationChangeToken(cts.Token);
}
[MemberNotNull(nameof(_endpoints))]
private void CreateEndpointsUnsynchronized()
{
- _endpoints = new List<Endpoint>();
+ var endpoints = new List<Endpoint>();
foreach (var dataSource in _dataSources)
{
- _endpoints.AddRange(dataSource.Endpoints);
+ endpoints.AddRange(dataSource.Endpoints);
}
+
+ // Only cache _endpoints after everything succeeds without throwing.
+ // We don't want to create a negative cache which would cause 404s when there should be 500s.
+ _endpoints = endpoints;
}
// Use private variable '_endpoints' to avoid initialization
diff --git a/src/Http/Routing/test/UnitTests/CompositeEndpointDataSourceTest.cs b/src/Http/Routing/test/UnitTests/CompositeEndpointDataSourceTest.cs
index 3cab4ecef2..4e6b5677ea 100644
--- a/src/Http/Routing/test/UnitTests/CompositeEndpointDataSourceTest.cs
+++ b/src/Http/Routing/test/UnitTests/CompositeEndpointDataSourceTest.cs
@@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.ObjectModel;
-using System.Linq;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing.Patterns;
@@ -59,6 +58,28 @@ public class CompositeEndpointDataSourceTest
}
[Fact]
+ public void RepeatedlyThrows_WhenChildDataSourcesThrow()
+ {
+ var ex = new Exception();
+ var compositeDataSource = new CompositeEndpointDataSource(new[]
+ {
+ new EndpointThrowingDataSource(ex),
+ });
+ var groupContext = new RouteGroupContext
+ {
+ Prefix = RoutePatternFactory.Parse(""),
+ Conventions = Array.Empty<Action<EndpointBuilder>>(),
+ FinallyConventions = Array.Empty<Action<EndpointBuilder>>(),
+ ApplicationServices = new ServiceCollection().BuildServiceProvider(),
+ };
+
+ Assert.Same(ex, Assert.Throws<Exception>(() => compositeDataSource.Endpoints));
+ Assert.Same(ex, Assert.Throws<Exception>(() => compositeDataSource.Endpoints));
+ Assert.Same(ex, Assert.Throws<Exception>(() => compositeDataSource.GetGroupedEndpoints(groupContext)));
+ Assert.Same(ex, Assert.Throws<Exception>(() => compositeDataSource.GetGroupedEndpoints(groupContext)));
+ }
+
+ [Fact]
public void Endpoints_ReturnsAllEndpoints_FromMultipleDataSources()
{
// Arrange
@@ -502,4 +523,17 @@ public class CompositeEndpointDataSourceTest
public override IChangeToken GetChangeToken() => NullChangeToken.Singleton;
}
+
+ private class EndpointThrowingDataSource : EndpointDataSource
+ {
+ private readonly Exception _ex;
+
+ public EndpointThrowingDataSource(Exception ex)
+ {
+ _ex = ex;
+ }
+
+ public override IReadOnlyList<Endpoint> Endpoints => throw _ex;
+ public override IChangeToken GetChangeToken() => NullChangeToken.Singleton;
+ }
}