Skip to content

Commit

Permalink
cache all appcontext switches (#2227)
Browse files Browse the repository at this point in the history
  • Loading branch information
Wraith2 authored Nov 21, 2023
1 parent 4f73355 commit b02cf41
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,23 @@ namespace Microsoft.Data.SqlClient
{
internal static partial class LocalAppContextSwitches
{
private enum Tristate : byte
{
NotInitialized = 0,
False = 1,
True = 2
}

internal const string MakeReadAsyncBlockingString = @"Switch.Microsoft.Data.SqlClient.MakeReadAsyncBlocking";
internal const string LegacyRowVersionNullString = @"Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior";
internal const string SuppressInsecureTLSWarningString = @"Switch.Microsoft.Data.SqlClient.SuppressInsecureTLSWarning";
internal const string UseMinimumLoginTimeoutString = @"Switch.Microsoft.Data.SqlClient.UseOneSecFloorInTimeoutCalculationDuringLogin";

private static bool? s_legacyRowVersionNullBehavior;
private static bool? s_suppressInsecureTLSWarning;
private static bool s_makeReadAsyncBlocking;
private static bool s_useMinimumLoginTimeout;
// this field is accessed through reflection in tests and should not be renamed or have the type changed without refactoring NullRow related tests
private static Tristate s_legacyRowVersionNullBehavior;
private static Tristate s_suppressInsecureTLSWarning;
private static Tristate s_makeReadAsyncBlocking;
private static Tristate s_useMinimumLoginTimeout;

#if !NETFRAMEWORK
static LocalAppContextSwitches()
Expand All @@ -36,7 +44,7 @@ static LocalAppContextSwitches()

#if NETFRAMEWORK
internal const string DisableTNIRByDefaultString = @"Switch.Microsoft.Data.SqlClient.DisableTNIRByDefaultInConnectionString";
private static bool s_disableTNIRByDefault;
private static Tristate s_disableTNIRByDefault;

/// <summary>
/// Transparent Network IP Resolution (TNIR) is a revision of the existing MultiSubnetFailover feature.
Expand All @@ -54,7 +62,23 @@ static LocalAppContextSwitches()
/// This app context switch defaults to 'false'.
/// </summary>
public static bool DisableTNIRByDefault
=> AppContext.TryGetSwitch(DisableTNIRByDefaultString, out s_disableTNIRByDefault) && s_disableTNIRByDefault;
{
get
{
if (s_disableTNIRByDefault == Tristate.NotInitialized)
{
if (AppContext.TryGetSwitch(DisableTNIRByDefaultString, out bool returnedValue) && returnedValue)
{
s_disableTNIRByDefault = Tristate.True;
}
else
{
s_disableTNIRByDefault = Tristate.False;
}
}
return s_disableTNIRByDefault == Tristate.True;
}
}
#endif

/// <summary>
Expand All @@ -66,13 +90,18 @@ public static bool SuppressInsecureTLSWarning
{
get
{
if (s_suppressInsecureTLSWarning is null)
if (s_suppressInsecureTLSWarning == Tristate.NotInitialized)
{
bool result;
result = AppContext.TryGetSwitch(SuppressInsecureTLSWarningString, out result) && result;
s_suppressInsecureTLSWarning = result;
if (AppContext.TryGetSwitch(SuppressInsecureTLSWarningString, out bool returnedValue) && returnedValue)
{
s_suppressInsecureTLSWarning = Tristate.True;
}
else
{
s_suppressInsecureTLSWarning = Tristate.False;
}
}
return s_suppressInsecureTLSWarning.Value;
return s_suppressInsecureTLSWarning == Tristate.True;
}
}

Expand All @@ -86,13 +115,18 @@ public static bool LegacyRowVersionNullBehavior
{
get
{
if (s_legacyRowVersionNullBehavior is null)
if (s_legacyRowVersionNullBehavior == Tristate.NotInitialized)
{
bool result;
result = AppContext.TryGetSwitch(LegacyRowVersionNullString, out result) && result;
s_legacyRowVersionNullBehavior = result;
if (AppContext.TryGetSwitch(LegacyRowVersionNullString, out bool returnedValue) && returnedValue)
{
s_legacyRowVersionNullBehavior = Tristate.True;
}
else
{
s_legacyRowVersionNullBehavior = Tristate.False;
}
}
return s_legacyRowVersionNullBehavior.Value;
return s_legacyRowVersionNullBehavior == Tristate.True;
}
}

Expand All @@ -101,14 +135,46 @@ public static bool LegacyRowVersionNullBehavior
/// This app context switch defaults to 'false'.
/// </summary>
public static bool MakeReadAsyncBlocking
=> AppContext.TryGetSwitch(MakeReadAsyncBlockingString, out s_makeReadAsyncBlocking) && s_makeReadAsyncBlocking;
{
get
{
if (s_makeReadAsyncBlocking == Tristate.NotInitialized)
{
if (AppContext.TryGetSwitch(MakeReadAsyncBlockingString, out bool returnedValue) && returnedValue)
{
s_makeReadAsyncBlocking = Tristate.True;
}
else
{
s_makeReadAsyncBlocking = Tristate.False;
}
}
return s_makeReadAsyncBlocking == Tristate.True;
}
}

/// <summary>
/// Specifies minimum login timeout to be set to 1 second instead of 0 seconds,
/// to prevent a login attempt from waiting indefinitely.
/// This app context switch defaults to 'true'.
/// </summary>
public static bool UseMinimumLoginTimeout
=> !AppContext.TryGetSwitch(UseMinimumLoginTimeoutString, out s_useMinimumLoginTimeout) || s_useMinimumLoginTimeout;
{
get
{
if (s_useMinimumLoginTimeout == Tristate.NotInitialized)
{
if (AppContext.TryGetSwitch(UseMinimumLoginTimeoutString, out bool returnedValue) && returnedValue)
{
s_useMinimumLoginTimeout = Tristate.True;
}
else
{
s_useMinimumLoginTimeout = Tristate.False;
}
}
return s_useMinimumLoginTimeout == Tristate.True;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ public static class DataReaderTest
{
private static readonly object s_rowVersionLock = new();

// this enum must mirror the definition in LocalAppContextSwitches
private enum Tristate : byte
{
NotInitialized = 0,
False = 1,
True = 2
}

[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))]
public static void LoadReaderIntoDataTableToTestGetSchemaTable()
{
Expand Down Expand Up @@ -261,7 +269,7 @@ public static void CheckNullRowVersionIsBDNull()
{
lock (s_rowVersionLock)
{
bool? originalValue = SetLegacyRowVersionNullBehavior(false);
Tristate originalValue = SetLegacyRowVersionNullBehavior(Tristate.False);
try
{
using SqlConnection con = new(DataTestUtility.TCPConnectionString);
Expand Down Expand Up @@ -298,7 +306,7 @@ public static void CheckLegacyNullRowVersionIsEmptyArray()
{
lock (s_rowVersionLock)
{
bool? originalValue = SetLegacyRowVersionNullBehavior(true);
Tristate originalValue = SetLegacyRowVersionNullBehavior(Tristate.True);
try
{
using SqlConnection con = new(DataTestUtility.TCPConnectionString);
Expand All @@ -323,11 +331,11 @@ public static void CheckLegacyNullRowVersionIsEmptyArray()
}
}

private static bool? SetLegacyRowVersionNullBehavior(bool? value)
private static Tristate SetLegacyRowVersionNullBehavior(Tristate value)
{
Type switchesType = typeof(SqlCommand).Assembly.GetType("Microsoft.Data.SqlClient.LocalAppContextSwitches");
FieldInfo switchField = switchesType.GetField("s_legacyRowVersionNullBehavior", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
bool? originalValue = (bool?)switchField.GetValue(null);
Tristate originalValue = (Tristate)switchField.GetValue(null);
switchField.SetValue(null, value);
return originalValue;
}
Expand Down

0 comments on commit b02cf41

Please sign in to comment.