Skip to content

Commit 997bf38

Browse files
Add | Use Minimum Login Timeout as 1 sec in .NET Core and enable behavior by default (#2012)
1 parent 4723181 commit 997bf38

File tree

6 files changed

+71
-62
lines changed

6 files changed

+71
-62
lines changed

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1263,7 +1263,14 @@ private void Login(ServerInfo server, TimeoutTimer timeout, string newPassword,
12631263
if (!timeout.IsInfinite)
12641264
{
12651265
long t = timeout.MillisecondsRemaining / 1000;
1266-
if ((long)int.MaxValue > t)
1266+
if (t == 0 && LocalAppContextSwitches.UseMinimumLoginTimeout)
1267+
{
1268+
// Take 1 as the minimum value, since 0 is treated as an infinite timeout
1269+
// to allow 1 second more for login to complete, since it should take only a few milliseconds.
1270+
t = 1;
1271+
}
1272+
1273+
if (int.MaxValue > t)
12671274
{
12681275
timeoutInSeconds = (int)t;
12691276
}
@@ -1279,7 +1286,8 @@ private void Login(ServerInfo server, TimeoutTimer timeout, string newPassword,
12791286

12801287
login.language = _currentLanguage;
12811288
if (!login.userInstance)
1282-
{ // Do not send attachdbfilename or database to SSE primary instance
1289+
{
1290+
// Do not send attachdbfilename or database to SSE primary instance
12831291
login.database = CurrentDatabase;
12841292
login.attachDBFilename = ConnectionOptions.AttachDBFilename;
12851293
}

src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -621,7 +621,6 @@
621621
<Compile Include="Microsoft\Data\RelationshipConverter.cs" />
622622
<Compile Include="Microsoft\Data\SqlClient\AlwaysEncryptedKeyConverter.Cng.cs" />
623623
<Compile Include="Microsoft\Data\SqlClient\assemblycache.cs" />
624-
<Compile Include="Microsoft\Data\SqlClient\LocalAppContextSwitches.netfx.cs" />
625624
<Compile Include="Microsoft\Data\SqlClient\LocalDBAPI.cs" />
626625
<Compile Include="Microsoft\Data\SqlClient\LocalDBConfig.cs" />
627626
<Compile Include="Microsoft\Data\SqlClient\Reliability\SqlConfigurableRetryLogicManager.LoadType.cs" />
@@ -735,4 +734,4 @@
735734
<Import Project="$(NetFxSource)tools\targets\GenerateThisAssemblyCs.targets" />
736735
<Import Project="$(NetFxSource)tools\targets\GenerateAssemblyRef.targets" />
737736
<Import Project="$(NetFxSource)tools\targets\GenerateAssemblyInfo.targets" />
738-
</Project>
737+
</Project>

src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.netfx.cs

Lines changed: 0 additions & 34 deletions
This file was deleted.

src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1530,10 +1530,11 @@ private void Login(ServerInfo server, TimeoutTimer timeout, string newPassword,
15301530
if (t == 0 && LocalAppContextSwitches.UseMinimumLoginTimeout)
15311531
{
15321532
// Take 1 as the minimum value, since 0 is treated as an infinite timeout
1533+
// to allow 1 second more for login to complete, since it should take only a few milliseconds.
15331534
t = 1;
15341535
}
15351536

1536-
if ((long)Int32.MaxValue > t)
1537+
if (int.MaxValue > t)
15371538
{
15381539
timeoutInSeconds = (int)t;
15391540
}

src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs

Lines changed: 57 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
// See the LICENSE file in the project root for more information.
44

55
using System;
6-
using System.Reflection;
7-
using System.Runtime.CompilerServices;
86

97
namespace Microsoft.Data.SqlClient
108
{
@@ -13,10 +11,12 @@ internal static partial class LocalAppContextSwitches
1311
internal const string MakeReadAsyncBlockingString = @"Switch.Microsoft.Data.SqlClient.MakeReadAsyncBlocking";
1412
internal const string LegacyRowVersionNullString = @"Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior";
1513
internal const string SuppressInsecureTLSWarningString = @"Switch.Microsoft.Data.SqlClient.SuppressInsecureTLSWarning";
14+
internal const string UseMinimumLoginTimeoutString = @"Switch.Microsoft.Data.SqlClient.UseOneSecFloorInTimeoutCalculationDuringLogin";
1615

16+
private static bool? s_legacyRowVersionNullBehavior;
17+
private static bool? s_suppressInsecureTLSWarning;
1718
private static bool s_makeReadAsyncBlocking;
18-
private static bool? s_LegacyRowVersionNullBehavior;
19-
private static bool? s_SuppressInsecureTLSWarning;
19+
private static bool s_useMinimumLoginTimeout;
2020

2121
#if !NETFRAMEWORK
2222
static LocalAppContextSwitches()
@@ -34,46 +34,81 @@ static LocalAppContextSwitches()
3434
}
3535
#endif
3636

37+
#if NETFRAMEWORK
38+
internal const string DisableTNIRByDefaultString = @"Switch.Microsoft.Data.SqlClient.DisableTNIRByDefaultInConnectionString";
39+
private static bool s_disableTNIRByDefault;
40+
41+
/// <summary>
42+
/// Transparent Network IP Resolution (TNIR) is a revision of the existing MultiSubnetFailover feature.
43+
/// TNIR affects the connection sequence of the driver in the case where the first resolved IP of the hostname
44+
/// doesn't respond and there are multiple IPs associated with the hostname.
45+
///
46+
/// TNIR interacts with MultiSubnetFailover to provide the following three connection sequences:
47+
/// 0: One IP is attempted, followed by all IPs in parallel
48+
/// 1: All IPs are attempted in parallel
49+
/// 2: All IPs are attempted one after another
50+
///
51+
/// TransparentNetworkIPResolution is enabled by default. MultiSubnetFailover is disabled by default.
52+
/// To disable TNIR, you can enable the app context switch.
53+
///
54+
/// This app context switch defaults to 'false'.
55+
/// </summary>
56+
public static bool DisableTNIRByDefault
57+
=> AppContext.TryGetSwitch(DisableTNIRByDefaultString, out s_disableTNIRByDefault) && s_disableTNIRByDefault;
58+
#endif
59+
60+
/// <summary>
61+
/// When using Encrypt=false in the connection string, a security warning is output to the console if the TLS version is 1.2 or lower.
62+
/// This warning can be suppressed by enabling this AppContext switch.
63+
/// This app context switch defaults to 'false'.
64+
/// </summary>
3765
public static bool SuppressInsecureTLSWarning
3866
{
3967
get
4068
{
41-
if (s_SuppressInsecureTLSWarning is null)
69+
if (s_suppressInsecureTLSWarning is null)
4270
{
4371
bool result;
44-
result = AppContext.TryGetSwitch(SuppressInsecureTLSWarningString, out result) ? result : false;
45-
s_SuppressInsecureTLSWarning = result;
72+
result = AppContext.TryGetSwitch(SuppressInsecureTLSWarningString, out result) && result;
73+
s_suppressInsecureTLSWarning = result;
4674
}
47-
return s_SuppressInsecureTLSWarning.Value;
48-
}
49-
}
50-
51-
public static bool MakeReadAsyncBlocking
52-
{
53-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
54-
get
55-
{
56-
return AppContext.TryGetSwitch(MakeReadAsyncBlockingString, out s_makeReadAsyncBlocking) ? s_makeReadAsyncBlocking : false;
75+
return s_suppressInsecureTLSWarning.Value;
5776
}
5877
}
5978

6079
/// <summary>
6180
/// In System.Data.SqlClient and Microsoft.Data.SqlClient prior to 3.0.0 a field with type Timestamp/RowVersion
6281
/// would return an empty byte array. This switch contols whether to preserve that behaviour on newer versions
63-
/// of Microsoft.Data.SqlClient, if this switch returns false an appropriate null value will be returned
82+
/// of Microsoft.Data.SqlClient, if this switch returns false an appropriate null value will be returned.
83+
/// This app context switch defaults to 'false'.
6484
/// </summary>
6585
public static bool LegacyRowVersionNullBehavior
6686
{
6787
get
6888
{
69-
if (s_LegacyRowVersionNullBehavior is null)
89+
if (s_legacyRowVersionNullBehavior is null)
7090
{
7191
bool result;
72-
result = AppContext.TryGetSwitch(LegacyRowVersionNullString, out result) ? result : false;
73-
s_LegacyRowVersionNullBehavior = result;
92+
result = AppContext.TryGetSwitch(LegacyRowVersionNullString, out result) && result;
93+
s_legacyRowVersionNullBehavior = result;
7494
}
75-
return s_LegacyRowVersionNullBehavior.Value;
95+
return s_legacyRowVersionNullBehavior.Value;
7696
}
7797
}
98+
99+
/// <summary>
100+
/// When enabled, ReadAsync runs asynchronously and does not block the calling thread.
101+
/// This app context switch defaults to 'false'.
102+
/// </summary>
103+
public static bool MakeReadAsyncBlocking
104+
=> AppContext.TryGetSwitch(MakeReadAsyncBlockingString, out s_makeReadAsyncBlocking) && s_makeReadAsyncBlocking;
105+
106+
/// <summary>
107+
/// Specifies minimum login timeout to be set to 1 second instead of 0 seconds,
108+
/// to prevent a login attempt from waiting indefinitely.
109+
/// This app context switch defaults to 'true'.
110+
/// </summary>
111+
public static bool UseMinimumLoginTimeout
112+
=> !AppContext.TryGetSwitch(UseMinimumLoginTimeoutString, out s_useMinimumLoginTimeout) || s_useMinimumLoginTimeout;
78113
}
79114
}

src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataReaderTest/DataReaderTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ public static void CheckLegacyNullRowVersionIsEmptyArray()
332332
private static bool? SetLegacyRowVersionNullBehavior(bool? value)
333333
{
334334
Type switchesType = typeof(SqlCommand).Assembly.GetType("Microsoft.Data.SqlClient.LocalAppContextSwitches");
335-
FieldInfo switchField = switchesType.GetField("s_LegacyRowVersionNullBehavior", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
335+
FieldInfo switchField = switchesType.GetField("s_legacyRowVersionNullBehavior", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
336336
bool? originalValue = (bool?)switchField.GetValue(null);
337337
switchField.SetValue(null, value);
338338
return originalValue;

0 commit comments

Comments
 (0)