Skip to content

Commit 3d1b01c

Browse files
author
Davoud Eshtehari
committed
First
Removed Switch.Microsoft.Data.SqlClient.EnableRetryLogic
1 parent fbfd5d7 commit 3d1b01c

File tree

11 files changed

+50
-162
lines changed

11 files changed

+50
-162
lines changed

BUILDGUIDE.md

-6
Original file line numberDiff line numberDiff line change
@@ -245,12 +245,6 @@ Scaled decimal parameter truncation can be enabled by enabling the below AppCont
245245

246246
**"Switch.Microsoft.Data.SqlClient.TruncateScaledDecimal"**
247247

248-
## Enabling configurable retry logic
249-
250-
To use this feature, you must enable the following AppContext switch at application startup:
251-
252-
**"Switch.Microsoft.Data.SqlClient.EnableRetryLogic"**
253-
254248
## Enabling row version null behavior
255249

256250
`SqlDataReader` returns a `DBNull` value instead of an empty `byte[]`. To enable the legacy behavior, you must enable the following AppContext switch on application startup:

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

+8-8
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,7 @@ private SqlInternalConnectionTds InternalTdsConnection
506506
}
507507
}
508508

509-
private static bool IsRetryEnabled => LocalAppContextSwitches.IsRetryEnabled;
509+
private bool IsRetriable => SqlConfigurableRetryFactory.IsRetriable(RetryLogicProvider);
510510

511511
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient/SqlCommand.xml' path='docs/members[@name="SqlCommand"]/RetryLogicProvider/*' />
512512
[Browsable(false)]
@@ -1101,7 +1101,7 @@ public override object ExecuteScalar()
11011101
statistics = SqlStatistics.StartTimer(Statistics);
11021102
WriteBeginExecuteEvent();
11031103
SqlDataReader ds;
1104-
ds = IsRetryEnabled ?
1104+
ds = IsRetriable ?
11051105
RunExecuteReaderWithRetry(0, RunBehavior.ReturnImmediately, returnStream: true) :
11061106
RunExecuteReader(0, RunBehavior.ReturnImmediately, returnStream: true, method: nameof(ExecuteScalar));
11071107
success = true;
@@ -1192,7 +1192,7 @@ public override int ExecuteNonQuery()
11921192
{
11931193
statistics = SqlStatistics.StartTimer(Statistics);
11941194
WriteBeginExecuteEvent();
1195-
if (IsRetryEnabled)
1195+
if (IsRetriable)
11961196
{
11971197
InternalExecuteNonQueryWithRetry(sendToPipe: false, timeout: CommandTimeout, out _, asyncWrite: false, inRetry: false);
11981198
}
@@ -1706,7 +1706,7 @@ public XmlReader ExecuteXmlReader()
17061706
WriteBeginExecuteEvent();
17071707
// use the reader to consume metadata
17081708
SqlDataReader ds;
1709-
ds = IsRetryEnabled ?
1709+
ds = IsRetriable ?
17101710
RunExecuteReaderWithRetry(CommandBehavior.SequentialAccess, RunBehavior.ReturnImmediately, returnStream: true) :
17111711
RunExecuteReader(CommandBehavior.SequentialAccess, RunBehavior.ReturnImmediately, returnStream: true);
17121712
success = true;
@@ -2043,7 +2043,7 @@ protected override DbDataReader ExecuteDbDataReader(CommandBehavior behavior)
20432043
{
20442044
WriteBeginExecuteEvent();
20452045
statistics = SqlStatistics.StartTimer(Statistics);
2046-
return IsRetryEnabled ?
2046+
return IsRetriable ?
20472047
RunExecuteReaderWithRetry(behavior, RunBehavior.ReturnImmediately, returnStream: true) :
20482048
RunExecuteReader(behavior, RunBehavior.ReturnImmediately, returnStream: true);
20492049
}
@@ -2548,7 +2548,7 @@ private SqlDataReader InternalEndExecuteReader(IAsyncResult asyncResult, bool is
25482548

25492549
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient/SqlCommand.xml' path='docs/members[@name="SqlCommand"]/ExecuteNonQueryAsync[@name="CancellationToken"]/*'/>
25502550
public override Task<int> ExecuteNonQueryAsync(CancellationToken cancellationToken)
2551-
=> IsRetryEnabled ?
2551+
=> IsRetriable ?
25522552
InternalExecuteNonQueryWithRetryAsync(cancellationToken) :
25532553
InternalExecuteNonQueryAsync(cancellationToken);
25542554

@@ -2648,7 +2648,7 @@ protected override Task<DbDataReader> ExecuteDbDataReaderAsync(CommandBehavior b
26482648

26492649
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient/SqlCommand.xml' path='docs/members[@name="SqlCommand"]/ExecuteReaderAsync[@name="commandBehaviorAndCancellationToken"]/*'/>
26502650
new public Task<SqlDataReader> ExecuteReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
2651-
=> IsRetryEnabled ?
2651+
=> IsRetriable ?
26522652
InternalExecuteReaderWithRetryAsync(behavior, cancellationToken) :
26532653
InternalExecuteReaderAsync(behavior, cancellationToken);
26542654

@@ -2821,7 +2821,7 @@ public Task<XmlReader> ExecuteXmlReaderAsync()
28212821

28222822
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient/SqlCommand.xml' path='docs/members[@name="SqlCommand"]/ExecuteXmlReaderAsync[@name="CancellationToken"]/*'/>
28232823
public Task<XmlReader> ExecuteXmlReaderAsync(CancellationToken cancellationToken)
2824-
=> IsRetryEnabled ?
2824+
=> IsRetriable ?
28252825
InternalExecuteXmlReaderWithRetryAsync(cancellationToken) :
28262826
InternalExecuteXmlReaderAsync(cancellationToken);
28272827

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ private static readonly ConcurrentDictionary<string, IList<string>> _ColumnEncry
114114
private static readonly Action<object> s_openAsyncCancel = OpenAsyncCancel;
115115
private static readonly Action<Task<object>, object> s_openAsyncComplete = OpenAsyncComplete;
116116

117-
private static bool IsRetryEnabled => LocalAppContextSwitches.IsRetryEnabled;
117+
private bool IsRetriable => SqlConfigurableRetryFactory.IsRetriable(RetryLogicProvider);
118118

119119
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient/SqlConnection.xml' path='docs/members[@name="SqlConnection"]/RetryLogicProvider/*' />
120120
[Browsable(false)]
@@ -1324,7 +1324,7 @@ public void Open(SqlConnectionOverrides overrides)
13241324
try
13251325
{
13261326
statistics = SqlStatistics.StartTimer(Statistics);
1327-
if (!(IsRetryEnabled ? TryOpenWithRetry(null, overrides) : TryOpen(null, overrides)))
1327+
if (!(IsRetriable ? TryOpenWithRetry(null, overrides) : TryOpen(null, overrides)))
13281328
{
13291329
throw ADP.InternalError(ADP.InternalErrorCode.SynchronousConnectReturnedPending);
13301330
}
@@ -1575,7 +1575,7 @@ private Task InternalOpenWithRetryAsync(CancellationToken cancellationToken)
15751575

15761576
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient/SqlConnection.xml' path='docs/members[@name="SqlConnection"]/OpenAsync/*' />
15771577
public override Task OpenAsync(CancellationToken cancellationToken)
1578-
=> IsRetryEnabled ?
1578+
=> IsRetriable ?
15791579
InternalOpenWithRetryAsync(cancellationToken) :
15801580
InternalOpenAsync(cancellationToken);
15811581

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

+12-12
Original file line numberDiff line numberDiff line change
@@ -620,7 +620,7 @@ private bool IsShiloh
620620
}
621621
}
622622

623-
private static bool IsRetryEnabled => LocalAppContextSwitches.IsRetryEnabled;
623+
private bool IsRetriable => SqlConfigurableRetryFactory.IsRetriable(RetryLogicProvider);
624624

625625
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient/SqlCommand.xml' path='docs/members[@name="SqlCommand"]/RetryLogicProvider/*' />
626626
[
@@ -1382,7 +1382,7 @@ public override object ExecuteScalar()
13821382
statistics = SqlStatistics.StartTimer(Statistics);
13831383
WriteBeginExecuteEvent();
13841384
SqlDataReader ds;
1385-
ds = IsRetryEnabled ?
1385+
ds = IsRetriable ?
13861386
RunExecuteReaderWithRetry(0, RunBehavior.ReturnImmediately, true, ADP.ExecuteScalar) :
13871387
RunExecuteReader(0, RunBehavior.ReturnImmediately, true, ADP.ExecuteScalar);
13881388
object result = CompleteExecuteScalar(ds, false);
@@ -1462,7 +1462,7 @@ public override int ExecuteNonQuery()
14621462
statistics = SqlStatistics.StartTimer(Statistics);
14631463
WriteBeginExecuteEvent();
14641464
bool usedCache;
1465-
if (IsRetryEnabled)
1465+
if (IsRetriable)
14661466
{
14671467
InternalExecuteNonQueryWithRetry(ADP.ExecuteNonQuery, sendToPipe: false, CommandTimeout, out usedCache, asyncWrite: false, inRetry: false);
14681468
}
@@ -2098,7 +2098,7 @@ public XmlReader ExecuteXmlReader()
20982098

20992099
// use the reader to consume metadata
21002100
SqlDataReader ds;
2101-
ds = IsRetryEnabled ?
2101+
ds = IsRetriable ?
21022102
RunExecuteReaderWithRetry(CommandBehavior.SequentialAccess, RunBehavior.ReturnImmediately, true, ADP.ExecuteXmlReader) :
21032103
RunExecuteReader(CommandBehavior.SequentialAccess, RunBehavior.ReturnImmediately, true, ADP.ExecuteXmlReader);
21042104
XmlReader result = CompleteXmlReader(ds);
@@ -2426,7 +2426,7 @@ private SqlDataReader ExecuteReaderWithRetry(CommandBehavior behavior, string me
24262426
try
24272427
{
24282428
statistics = SqlStatistics.StartTimer(Statistics);
2429-
return IsRetryEnabled ?
2429+
return IsRetriable ?
24302430
ExecuteReaderWithRetry(CommandBehavior.Default, ADP.ExecuteReader) :
24312431
ExecuteReader(CommandBehavior.Default, ADP.ExecuteReader);
24322432
}
@@ -2444,7 +2444,7 @@ private SqlDataReader ExecuteReaderWithRetry(CommandBehavior behavior, string me
24442444
{
24452445
SqlClientEventSource.Log.TryCorrelationTraceEvent("<sc.SqlCommand.ExecuteReader|API|Correlation> ObjectID {0}, behavior={1}, ActivityID {2}", ObjectID, (int)behavior, ActivityCorrelator.Current);
24462446

2447-
return IsRetryEnabled ?
2447+
return IsRetriable ?
24482448
ExecuteReaderWithRetry(behavior, ADP.ExecuteReader) :
24492449
ExecuteReader(behavior, ADP.ExecuteReader);
24502450
}
@@ -2960,7 +2960,7 @@ private Task<int> InternalExecuteNonQueryWithRetryAsync(CancellationToken cancel
29602960

29612961
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient/SqlCommand.xml' path='docs/members[@name="SqlCommand"]/ExecuteNonQueryAsync[@name="CancellationToken"]/*'/>
29622962
public override Task<int> ExecuteNonQueryAsync(CancellationToken cancellationToken)
2963-
=> IsRetryEnabled ?
2963+
=> IsRetriable ?
29642964
InternalExecuteNonQueryWithRetryAsync(cancellationToken) :
29652965
InternalExecuteNonQueryAsync(cancellationToken);
29662966

@@ -3039,25 +3039,25 @@ private Task<SqlDataReader> InternalExecuteReaderWithRetryAsync(CommandBehavior
30393039

30403040
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient/SqlCommand.xml' path='docs/members[@name="SqlCommand"]/ExecuteReaderAsync[@name="default"]/*'/>
30413041
new public Task<SqlDataReader> ExecuteReaderAsync()
3042-
=> IsRetryEnabled ?
3042+
=> IsRetriable ?
30433043
InternalExecuteReaderWithRetryAsync(CommandBehavior.Default, CancellationToken.None) :
30443044
InternalExecuteReaderAsync(CommandBehavior.Default, CancellationToken.None);
30453045

30463046
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient/SqlCommand.xml' path='docs/members[@name="SqlCommand"]/ExecuteReaderAsync[@name="CommandBehavior"]/*'/>
30473047
new public Task<SqlDataReader> ExecuteReaderAsync(CommandBehavior behavior)
3048-
=> IsRetryEnabled ?
3048+
=> IsRetriable ?
30493049
InternalExecuteReaderWithRetryAsync(behavior, CancellationToken.None) :
30503050
InternalExecuteReaderAsync(behavior, CancellationToken.None);
30513051

30523052
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient/SqlCommand.xml' path='docs/members[@name="SqlCommand"]/ExecuteReaderAsync[@name="CancellationToken"]/*'/>
30533053
new public Task<SqlDataReader> ExecuteReaderAsync(CancellationToken cancellationToken)
3054-
=> IsRetryEnabled ?
3054+
=> IsRetriable ?
30553055
InternalExecuteReaderWithRetryAsync(CommandBehavior.Default, cancellationToken) :
30563056
InternalExecuteReaderAsync(CommandBehavior.Default, cancellationToken);
30573057

30583058
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient/SqlCommand.xml' path='docs/members[@name="SqlCommand"]/ExecuteReaderAsync[@name="commandBehaviorAndCancellationToken"]/*'/>
30593059
new public Task<SqlDataReader> ExecuteReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
3060-
=> IsRetryEnabled ?
3060+
=> IsRetriable ?
30613061
InternalExecuteReaderWithRetryAsync(behavior, cancellationToken) :
30623062
InternalExecuteReaderAsync(behavior, cancellationToken);
30633063

@@ -3203,7 +3203,7 @@ private Task<XmlReader> InternalExecuteXmlReaderWithRetryAsync(CancellationToken
32033203

32043204
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient/SqlCommand.xml' path='docs/members[@name="SqlCommand"]/ExecuteXmlReaderAsync[@name="CancellationToken"]/*'/>
32053205
public Task<XmlReader> ExecuteXmlReaderAsync(CancellationToken cancellationToken)
3206-
=> IsRetryEnabled ?
3206+
=> IsRetriable ?
32073207
InternalExecuteXmlReaderWithRetryAsync(cancellationToken) :
32083208
InternalExecuteXmlReaderAsync(cancellationToken);
32093209

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ internal List<string> GetColumnEncryptionCustomKeyStoreProvidersNames()
310310

311311
// Retry Logic
312312
private SqlRetryLogicBaseProvider _retryLogicProvider;
313-
private static bool IsRetryEnabled => LocalAppContextSwitches.IsRetryEnabled;
313+
private bool IsRetriable => SqlConfigurableRetryFactory.IsRetriable(RetryLogicProvider);
314314

315315
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient/SqlConnection.xml' path='docs/members[@name="SqlConnection"]/RetryLogicProvider/*' />
316316
[
@@ -1648,7 +1648,7 @@ public void Open(SqlConnectionOverrides overrides)
16481648
{
16491649
statistics = SqlStatistics.StartTimer(Statistics);
16501650

1651-
if (!(IsRetryEnabled ? TryOpenWithRetry(null, overrides) : TryOpen(null, overrides)))
1651+
if (!(IsRetriable ? TryOpenWithRetry(null, overrides) : TryOpen(null, overrides)))
16521652
{
16531653
throw ADP.InternalError(ADP.InternalErrorCode.SynchronousConnectReturnedPending);
16541654
}
@@ -1882,7 +1882,7 @@ private Task InternalOpenWithRetryAsync(CancellationToken cancellationToken)
18821882

18831883
/// <include file='..\..\..\..\..\..\..\doc\snippets\Microsoft.Data.SqlClient\SqlConnection.xml' path='docs/members[@name="SqlConnection"]/OpenAsync/*' />
18841884
public override Task OpenAsync(CancellationToken cancellationToken)
1885-
=> IsRetryEnabled ?
1885+
=> IsRetriable ?
18861886
InternalOpenWithRetryAsync(cancellationToken) :
18871887
InternalOpenAsync(cancellationToken);
18881888

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

-17
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,10 @@ internal static partial class LocalAppContextSwitches
1414
internal const string MakeReadAsyncBlockingString = @"Switch.Microsoft.Data.SqlClient.MakeReadAsyncBlocking";
1515
internal const string LegacyRowVersionNullString = @"Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior";
1616
internal const string UseSystemDefaultSecureProtocolsString = @"Switch.Microsoft.Data.SqlClient.UseSystemDefaultSecureProtocols";
17-
// safety switch
18-
internal const string EnableRetryLogicSwitch = "Switch.Microsoft.Data.SqlClient.EnableRetryLogic";
1917

2018
private static bool _makeReadAsyncBlocking;
2119
private static bool? s_LegacyRowVersionNullBehavior;
2220
private static bool? s_UseSystemDefaultSecureProtocols;
23-
private static bool? s_isRetryEnabled = null;
2421

2522
#if !NETFRAMEWORK
2623
static LocalAppContextSwitches()
@@ -38,20 +35,6 @@ static LocalAppContextSwitches()
3835
}
3936
#endif
4037

41-
internal static bool IsRetryEnabled
42-
{
43-
get
44-
{
45-
if (s_isRetryEnabled is null)
46-
{
47-
bool result;
48-
result = AppContext.TryGetSwitch(EnableRetryLogicSwitch, out result) ? result : false;
49-
s_isRetryEnabled = result;
50-
}
51-
return s_isRetryEnabled.Value;
52-
}
53-
}
54-
5538
public static bool MakeReadAsyncBlocking
5639
{
5740
[MethodImpl(MethodImplOptions.AggressiveInlining)]

src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Reliability/SqlConfigurableRetryFactory.cs

+6
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,12 @@ public static SqlRetryLogicBaseProvider CreateNoneRetryProvider()
101101
return new SqlRetryLogicProvider(retryLogic);
102102
}
103103

104+
/// <summary>
105+
/// Verifies the provider which is not null and doesn't include SqlNoneIntervalEnumerator enumerator object.
106+
/// </summary>
107+
internal static bool IsRetriable(SqlRetryLogicBaseProvider provider)
108+
=> provider is not null && (provider.RetryLogic is null || provider.RetryLogic.RetryIntervalEnumerator is not SqlNoneIntervalEnumerator);
109+
104110
/// Return true if the exception is a transient fault.
105111
private static bool TransientErrorsCondition(Exception e, IEnumerable<int> retriableConditions)
106112
{

src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/RetryLogic/RetryLogicConfigHelper.cs

+3-9
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,8 @@ public static SqlRetryLogicBaseProvider GetConnectionProvider(object loader)
9191
public static SqlRetryLogicBaseProvider GetCommandProvider(object loader)
9292
=> GetValue<SqlRetryLogicBaseProvider>(loader, s_configurationLoaderType, "CommandProvider");
9393

94-
public static void AssessProvider(SqlRetryLogicBaseProvider provider, RetryLogicConfigs option, bool switchValue)
95-
{
96-
AssessRetryLogic(provider.RetryLogic, option);
97-
98-
AppContext.TryGetSwitch(RetryLogicTestHelper.RetryAppContextSwitch, out bool value);
99-
Assert.Equal(switchValue, value);
100-
}
94+
public static void AssessProvider(SqlRetryLogicBaseProvider provider, RetryLogicConfigs option)
95+
=> AssessRetryLogic(provider.RetryLogic, option);
10196

10297
public static void AssessRetryLogic(SqlRetryLogicBase retryLogic, RetryLogicConfigs option)
10398
{
@@ -142,9 +137,8 @@ public static IEnumerable<object[]> GetIivalidTimes()
142137
}
143138
}
144139

145-
public static object ReturnLoaderAndProviders(RetryLogicConfigs cnnCfg, RetryLogicConfigs cmdCfg, bool switchValue, out SqlRetryLogicBaseProvider cnnProvider, out SqlRetryLogicBaseProvider cmdProvider)
140+
public static object ReturnLoaderAndProviders(RetryLogicConfigs cnnCfg, RetryLogicConfigs cmdCfg, out SqlRetryLogicBaseProvider cnnProvider, out SqlRetryLogicBaseProvider cmdProvider)
146141
{
147-
ApplyContextSwitchByManager(RetryLogicTestHelper.RetryAppContextSwitch, switchValue);
148142
var loaderObj = CreateLoader(cnnCfg, cmdCfg);
149143
cnnProvider = GetConnectionProvider(loaderObj);
150144
cmdProvider = GetCommandProvider(loaderObj);

0 commit comments

Comments
 (0)