Skip to content

Commit 1ea47f1

Browse files
Run users options last (#15121)
1 parent 08608af commit 1ea47f1

File tree

8 files changed

+113
-13
lines changed

8 files changed

+113
-13
lines changed

src/SignalR/perf/Microbenchmarks/DefaultHubDispatcherBenchmark.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ public void GlobalSetup()
3737
_dispatcher = new DefaultHubDispatcher<TestHub>(
3838
serviceScopeFactory,
3939
new HubContext<TestHub>(new DefaultHubLifetimeManager<TestHub>(NullLogger<DefaultHubLifetimeManager<TestHub>>.Instance)),
40-
Options.Create(new HubOptions<TestHub>()),
41-
Options.Create(new HubOptions()),
40+
enableDetailedErrors: false,
4241
new Logger<DefaultHubDispatcher<TestHub>>(NullLoggerFactory.Instance));
4342

4443
var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default);

src/SignalR/server/Core/src/HubConnectionHandler.cs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,22 @@ IServiceScopeFactory serviceScopeFactory
5959
_logger = loggerFactory.CreateLogger<HubConnectionHandler<THub>>();
6060
_userIdProvider = userIdProvider;
6161

62-
_enableDetailedErrors = _hubOptions.EnableDetailedErrors ?? _globalHubOptions.EnableDetailedErrors ?? false;
63-
_maximumMessageSize = _hubOptions.MaximumReceiveMessageSize ?? _globalHubOptions.MaximumReceiveMessageSize;
62+
_enableDetailedErrors = false;
63+
if (_hubOptions.UserHasSetValues)
64+
{
65+
_maximumMessageSize = _hubOptions.MaximumReceiveMessageSize;
66+
_enableDetailedErrors = _hubOptions.EnableDetailedErrors ?? _enableDetailedErrors;
67+
}
68+
else
69+
{
70+
_maximumMessageSize = _globalHubOptions.MaximumReceiveMessageSize;
71+
_enableDetailedErrors = _globalHubOptions.EnableDetailedErrors ?? _enableDetailedErrors;
72+
}
6473

6574
_dispatcher = new DefaultHubDispatcher<THub>(
6675
serviceScopeFactory,
6776
new HubContext<THub>(lifetimeManager),
68-
hubOptions,
69-
globalHubOptions,
77+
_enableDetailedErrors,
7078
new Logger<DefaultHubDispatcher<THub>>(loggerFactory));
7179
}
7280

src/SignalR/server/Core/src/HubOptionsSetup`T.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ public void Configure(HubOptions<THub> options)
2323
}
2424
options.KeepAliveInterval = _hubOptions.KeepAliveInterval;
2525
options.HandshakeTimeout = _hubOptions.HandshakeTimeout;
26+
options.ClientTimeoutInterval = _hubOptions.ClientTimeoutInterval;
27+
options.EnableDetailedErrors = _hubOptions.EnableDetailedErrors;
28+
options.MaximumReceiveMessageSize = _hubOptions.MaximumReceiveMessageSize;
29+
options.StreamBufferCapacity = _hubOptions.StreamBufferCapacity;
30+
31+
options.UserHasSetValues = true;
2632
}
2733
}
2834
}

src/SignalR/server/Core/src/HubOptions`T.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) .NET Foundation. All rights reserved.
1+
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
namespace Microsoft.AspNetCore.SignalR
@@ -9,5 +9,6 @@ namespace Microsoft.AspNetCore.SignalR
99
/// <typeparam name="THub">The hub type to configure.</typeparam>
1010
public class HubOptions<THub> : HubOptions where THub : Hub
1111
{
12+
internal bool UserHasSetValues { get; set; }
1213
}
1314
}

src/SignalR/server/Core/src/Internal/DefaultHubDispatcher.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,11 @@ internal partial class DefaultHubDispatcher<THub> : HubDispatcher<THub> where TH
2828
private readonly ILogger<HubDispatcher<THub>> _logger;
2929
private readonly bool _enableDetailedErrors;
3030

31-
public DefaultHubDispatcher(IServiceScopeFactory serviceScopeFactory, IHubContext<THub> hubContext, IOptions<HubOptions<THub>> hubOptions,
32-
IOptions<HubOptions> globalHubOptions, ILogger<DefaultHubDispatcher<THub>> logger)
31+
public DefaultHubDispatcher(IServiceScopeFactory serviceScopeFactory, IHubContext<THub> hubContext, bool enableDetailedErrors, ILogger<DefaultHubDispatcher<THub>> logger)
3332
{
3433
_serviceScopeFactory = serviceScopeFactory;
3534
_hubContext = hubContext;
36-
_enableDetailedErrors = hubOptions.Value.EnableDetailedErrors ?? globalHubOptions.Value.EnableDetailedErrors ?? false;
35+
_enableDetailedErrors = enableDetailedErrors;
3736
_logger = logger;
3837
DiscoverHubMethods();
3938
}

src/SignalR/server/SignalR/src/SignalRDependencyInjectionExtensions.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using System;
55
using Microsoft.AspNetCore.Builder;
66
using Microsoft.AspNetCore.SignalR;
7-
using Microsoft.AspNetCore.SignalR.Internal;
87
using Microsoft.Extensions.DependencyInjection.Extensions;
98
using Microsoft.Extensions.Options;
109

@@ -67,8 +66,10 @@ public static ISignalRServerBuilder AddSignalR(this IServiceCollection services,
6766
throw new ArgumentNullException(nameof(services));
6867
}
6968

70-
return services.Configure(configure)
71-
.AddSignalR();
69+
var signalrBuilder = services.AddSignalR();
70+
// Setup users settings after we've setup ours
71+
services.Configure(configure);
72+
return signalrBuilder;
7273
}
7374
}
7475
}

src/SignalR/server/SignalR/test/AddSignalRTests.cs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright(c) .NET Foundation.All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

4+
using System;
45
using System.Collections.Generic;
56
using System.Threading;
67
using System.Threading.Tasks;
@@ -81,6 +82,29 @@ public void HubSpecificOptionsDoNotAffectGlobalHubOptions()
8182
Assert.Equal(0, serviceProvider.GetRequiredService<IOptions<HubOptions<CustomHub>>>().Value.SupportedProtocols.Count);
8283
}
8384

85+
[Fact]
86+
public void HubSpecificOptionsHaveSameValuesAsGlobalHubOptions()
87+
{
88+
var serviceCollection = new ServiceCollection();
89+
90+
serviceCollection.AddSignalR().AddHubOptions<CustomHub>(options =>
91+
{
92+
});
93+
94+
var serviceProvider = serviceCollection.BuildServiceProvider();
95+
var hubOptions = serviceProvider.GetRequiredService<IOptions<HubOptions<CustomHub>>>().Value;
96+
var globalHubOptions = serviceProvider.GetRequiredService<IOptions<HubOptions>>().Value;
97+
98+
Assert.Equal(globalHubOptions.MaximumReceiveMessageSize, hubOptions.MaximumReceiveMessageSize);
99+
Assert.Equal(globalHubOptions.StreamBufferCapacity, hubOptions.StreamBufferCapacity);
100+
Assert.Equal(globalHubOptions.EnableDetailedErrors, hubOptions.EnableDetailedErrors);
101+
Assert.Equal(globalHubOptions.KeepAliveInterval, hubOptions.KeepAliveInterval);
102+
Assert.Equal(globalHubOptions.HandshakeTimeout, hubOptions.HandshakeTimeout);
103+
Assert.Equal(globalHubOptions.SupportedProtocols, hubOptions.SupportedProtocols);
104+
Assert.Equal(globalHubOptions.ClientTimeoutInterval, hubOptions.ClientTimeoutInterval);
105+
Assert.True(hubOptions.UserHasSetValues);
106+
}
107+
84108
[Fact]
85109
public void StreamBufferCapacityGetSet()
86110
{
@@ -94,6 +118,36 @@ public void StreamBufferCapacityGetSet()
94118
var serviceProvider = serviceCollection.BuildServiceProvider();
95119
Assert.Equal(42, serviceProvider.GetRequiredService<IOptions<HubOptions<CustomHub>>>().Value.StreamBufferCapacity);
96120
}
121+
122+
[Fact]
123+
public void UserSpecifiedOptionsRunAfterDefaultOptions()
124+
{
125+
var serviceCollection = new ServiceCollection();
126+
127+
// null is special when the default options setup runs, so we set to null to verify that our options run after the default
128+
// setup runs
129+
serviceCollection.AddSignalR(options =>
130+
{
131+
options.MaximumReceiveMessageSize = null;
132+
options.StreamBufferCapacity = null;
133+
options.EnableDetailedErrors = null;
134+
options.KeepAliveInterval = null;
135+
options.HandshakeTimeout = null;
136+
options.SupportedProtocols = null;
137+
options.ClientTimeoutInterval = TimeSpan.FromSeconds(1);
138+
});
139+
140+
var serviceProvider = serviceCollection.BuildServiceProvider();
141+
142+
var globalOptions = serviceProvider.GetRequiredService<IOptions<HubOptions>>().Value;
143+
Assert.Null(globalOptions.MaximumReceiveMessageSize);
144+
Assert.Null(globalOptions.StreamBufferCapacity);
145+
Assert.Null(globalOptions.EnableDetailedErrors);
146+
Assert.Null(globalOptions.KeepAliveInterval);
147+
Assert.Null(globalOptions.HandshakeTimeout);
148+
Assert.Null(globalOptions.SupportedProtocols);
149+
Assert.Equal(TimeSpan.FromSeconds(1), globalOptions.ClientTimeoutInterval);
150+
}
97151
}
98152

99153
public class CustomHub : Hub

src/SignalR/server/SignalR/test/HubConnectionHandlerTests.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3834,6 +3834,38 @@ public async Task ConnectionCloseCleansUploadStreams()
38343834
}
38353835
}
38363836

3837+
[Fact]
3838+
public async Task SpecificHubOptionForMaximumReceiveMessageSizeIsUsedOverGlobalHubOption()
3839+
{
3840+
var serviceProvider = HubConnectionHandlerTestUtils.CreateServiceProvider(serviceBuilder =>
3841+
{
3842+
serviceBuilder.AddSignalR(o =>
3843+
{
3844+
// ConnectAsync would fail if this value was used
3845+
o.MaximumReceiveMessageSize = 1;
3846+
}).AddHubOptions<MethodHub>(o =>
3847+
{
3848+
// null is treated as both no-limit and not set, this test verifies that we track if the user explicitly sets the value
3849+
o.MaximumReceiveMessageSize = null;
3850+
});
3851+
});
3852+
var connectionHandler = serviceProvider.GetService<HubConnectionHandler<MethodHub>>();
3853+
3854+
using (StartVerifiableLog())
3855+
{
3856+
using var client = new TestClient();
3857+
3858+
var connectionHandlerTask = await client.ConnectAsync(connectionHandler);
3859+
3860+
// Wait for a connection, or for the endpoint to fail.
3861+
await client.Connected.OrThrowIfOtherFails(connectionHandlerTask).OrTimeout();
3862+
3863+
await client.DisposeAsync().OrTimeout();
3864+
3865+
await connectionHandlerTask.OrTimeout();
3866+
}
3867+
}
3868+
38373869
private class CustomHubActivator<THub> : IHubActivator<THub> where THub : Hub
38383870
{
38393871
public int ReleaseCount;

0 commit comments

Comments
 (0)