Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support ConfigurationManager in Net Standard for configurable retry logic #1090

Merged
merged 7 commits into from
Jun 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,14 @@
<Compile Include="..\..\src\Microsoft\Data\SqlClient\Reliability\SqlConfigurableRetryLogicManager.cs">
<Link>Microsoft\Data\SqlClient\Reliability\SqlConfigurableRetryLogicManager.cs</Link>
</Compile>
<Compile Include="..\..\src\Microsoft\Data\SqlClient\Reliability\SqlConfigurableRetryLogicLoader.cs">
<Link>Microsoft\Data\SqlClient\Reliability\SqlConfigurableRetryLogicLoader.cs</Link>
</Compile>
<Compile Include="..\..\src\Microsoft\Data\SqlClient\Reliability\AppConfigManager.cs">
<Link>Microsoft\Data\SqlClient\Reliability\AppConfigManager.cs</Link>
</Compile>
<Compile Include="Microsoft\Data\SqlClient\Reliability\SqlConfigurableRetryLogicManager.NetCoreApp.cs" />
cheenamalhotra marked this conversation as resolved.
Show resolved Hide resolved
<Compile Include="Microsoft\Data\SqlClient\SqlAppContextSwitchManager.NetCoreApp.cs" />
<Compile Include="..\..\src\Microsoft\Data\SqlClient\SqlUtil.cs">
<Link>Microsoft\Data\SqlClient\SqlUtil.cs</Link>
</Compile>
Expand All @@ -334,7 +342,6 @@
<Compile Include="Microsoft\Data\SqlClient\SqlDelegatedTransaction.NetStandard.cs" />
<Compile Include="Microsoft\Data\SqlClient\TdsParser.NetStandard.cs" />
<Compile Include="Microsoft\Data\SqlClient\SNI\SslOverTdsStream.NetStandard.cs" />
<Compile Include="Microsoft\Data\SqlClient\Reliability\SqlConfigurableRetryLogicManager.NetStandard.cs" />
</ItemGroup>
<ItemGroup Condition="'$(OSGroup)' != 'AnyOS' AND '$(TargetFramework)' != 'netstandard2.0'">
<Compile Include="..\..\src\Microsoft\Data\SqlClient\AlwaysEncryptedAttestationException.cs">
Expand Down Expand Up @@ -383,14 +390,6 @@
<Compile Include="Microsoft\Data\SqlClient\SNI\SslOverTdsStream.NetCoreApp.cs" />
<Compile Include="Microsoft\Data\SqlClient\SqlConnectionFactory.AssemblyLoadContext.cs" />
<Compile Include="Microsoft\Data\SqlClient\SqlDependencyUtils.AssemblyLoadContext.cs" />
<Compile Include="..\..\src\Microsoft\Data\SqlClient\Reliability\SqlConfigurableRetryLogicManager.CreateProvider.cs">
<Link>Microsoft\Data\SqlClient\Reliability\SqlConfigurableRetryLogicManager.CreateProvider.NetCoreApp.cs</Link>
</Compile>
<Compile Include="..\..\src\Microsoft\Data\SqlClient\Reliability\AppConfigManager.cs">
<Link>Microsoft\Data\SqlClient\Reliability\AppConfigManager.NetCoreApp.cs</Link>
</Compile>
<Compile Include="Microsoft\Data\SqlClient\Reliability\SqlConfigurableRetryLogicManager.NetCoreApp.cs" />
<Compile Include="Microsoft\Data\SqlClient\Reliability\SqlAppContextSwitchManager.NetCoreApp.cs" />
</ItemGroup>
<ItemGroup Condition="'$(OSGroup)' != 'AnyOS' AND '$(TargetFramework)' != 'netstandard2.0' AND '$(BuildSimulator)' == 'true'">
<Compile Include="Microsoft\Data\SqlClient\SimulatorEnclaveProvider.NetCoreApp.cs" />
Expand Down Expand Up @@ -838,7 +837,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Condition="'$(TargetsWindows)' == 'true' and '$(IsUAPAssembly)' != 'true'" Include="Microsoft.Win32.Registry" Version="$(MicrosoftWin32RegistryVersion)" />
<PackageReference Condition="'$(TargetGroup)' == 'netcoreapp'" Include="System.Configuration.ConfigurationManager" Version="$(SystemConfigurationConfigurationManagerVersion)" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="$(SystemConfigurationConfigurationManagerVersion)" />
<PackageReference Include="System.Security.Permissions" Version="$(SystemSecurityPermissionsVersion)" />
<PackageReference Include="System.Security.Principal.Windows" Version="$(SystemSecurityPrincipalWindowsVersion)" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="$(SystemTextEncodingCodePagesVersion)" />
Expand All @@ -857,6 +856,7 @@
<PackageReference Include="System.Resources.ResourceManager" Version="$(SystemResourcesResourceManagerVersion)" />
<PackageReference Include="System.Buffers" Version="$(SystemBuffersVersion)" />
<PackageReference Include="System.Runtime.Caching" Version="$(SystemRuntimeCachingVersion)" />
<PackageReference Condition="$(TargetGroup) == 'netstandard'" Include="System.Runtime.Loader" Version="$(SystemRuntimeLoaderVersion)" />
<PackageReference Include="System.Security.Cryptography.Cng" Version="$(SystemSecurityCryptographyCngVersion)" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="$(MicrosoftSourceLinkGitHubVersion)" PrivateAssets="All" />
</ItemGroup>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -493,20 +493,7 @@ private SqlInternalConnectionTds InternalTdsConnection
}
}

private bool? _isRetryEnabled;
private bool IsRetryEnabled
{
get
{
if (_isRetryEnabled == null)
{
bool result;
result = AppContext.TryGetSwitch(SqlRetryLogicProvider.EnableRetryLogicSwitch, out result) ? result : false;
_isRetryEnabled = result;
}
return (bool)_isRetryEnabled;
}
}
private static bool IsRetryEnabled => LocalAppContextSwitches.IsRetryEnabled;

/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient/SqlCommand.xml' path='docs/members[@name="SqlCommand"]/RetryLogicProvider/*' />
public SqlRetryLogicBaseProvider RetryLogicProvider
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,20 +111,7 @@ private static readonly ConcurrentDictionary<string, IList<string>> _ColumnEncry
private static readonly Action<object> s_openAsyncCancel = OpenAsyncCancel;
private static readonly Action<Task<object>, object> s_openAsyncComplete = OpenAsyncComplete;

private bool? _isRetryEnabled;
private bool IsRetryEnabled
{
get
{
if (_isRetryEnabled == null)
{
bool result;
result = AppContext.TryGetSwitch(SqlRetryLogicProvider.EnableRetryLogicSwitch, out result) ? result : false;
_isRetryEnabled = result;
}
return (bool)_isRetryEnabled;
}
}
private static bool IsRetryEnabled => LocalAppContextSwitches.IsRetryEnabled;

/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient/SqlConnection.xml' path='docs/members[@name="SqlConnection"]/RetryLogicProvider/*' />
public SqlRetryLogicBaseProvider RetryLogicProvider
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -401,8 +401,8 @@
<Compile Include="..\..\src\Microsoft\Data\SqlClient\Reliability\SqlConfigurableRetryLogicManager.cs">
<Link>Microsoft\Data\SqlClient\Reliability\SqlConfigurableRetryLogicManager.cs</Link>
</Compile>
<Compile Include="..\..\src\Microsoft\Data\SqlClient\Reliability\SqlConfigurableRetryLogicManager.CreateProvider.cs">
<Link>Microsoft\Data\SqlClient\Reliability\SqlConfigurableRetryLogicManager.CreateProvider.cs</Link>
<Compile Include="..\..\src\Microsoft\Data\SqlClient\Reliability\SqlConfigurableRetryLogicLoader.cs">
<Link>Microsoft\Data\SqlClient\Reliability\SqlConfigurableRetryLogicLoader.cs</Link>
</Compile>
<Compile Include="..\..\src\Microsoft\Data\SqlClient\Reliability\AppConfigManager.cs">
<Link>Microsoft\Data\SqlClient\Reliability\AppConfigManager.cs</Link>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -616,20 +616,7 @@ private bool IsShiloh
}
}

private bool? _isRetryEnabled;
private bool IsRetryEnabled
{
get
{
if (_isRetryEnabled == null)
{
bool result;
result = AppContext.TryGetSwitch(SqlRetryLogicProvider.EnableRetryLogicSwitch, out result) ? result : false;
_isRetryEnabled = result;
}
return (bool)_isRetryEnabled;
}
}
private static bool IsRetryEnabled => LocalAppContextSwitches.IsRetryEnabled;

/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient/SqlCommand.xml' path='docs/members[@name="SqlCommand"]/RetryLogicProvider/*' />
[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -310,20 +310,7 @@ internal List<string> GetColumnEncryptionCustomKeyStoreProvidersNames()

// Retry Logic
private SqlRetryLogicBaseProvider _retryLogicProvider;
private bool? _isRetryEnabled;
private bool IsRetryEnabled
{
get
{
if (_isRetryEnabled == null)
{
bool result;
result = AppContext.TryGetSwitch(SqlRetryLogicProvider.EnableRetryLogicSwitch, out result) ? result : false;
_isRetryEnabled = result;
}
return (bool)_isRetryEnabled;
}
}
private static bool IsRetryEnabled => LocalAppContextSwitches.IsRetryEnabled;

/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient/SqlConnection.xml' path='docs/members[@name="SqlConnection"]/RetryLogicProvider/*' />
[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,52 @@
// See the LICENSE file in the project root for more information.

using System;
using System.Reflection;
using System.Runtime.CompilerServices;

namespace Microsoft.Data.SqlClient
{
internal static partial class LocalAppContextSwitches
{
private const string TypeName = nameof(LocalAppContextSwitches);
internal const string MakeReadAsyncBlockingString = @"Switch.Microsoft.Data.SqlClient.MakeReadAsyncBlocking";
internal const string LegacyRowVersionNullString = @"Switch.Microsoft.Data.SqlClient.LegacyRowVersionNullBehavior";
// safety switch
internal const string EnableRetryLogicSwitch = "Switch.Microsoft.Data.SqlClient.EnableRetryLogic";

private static bool _makeReadAsyncBlocking;
private static bool? s_LegacyRowVersionNullBehavior;
private static bool? s_isRetryEnabled = null;

#if !NETFRAMEWORK
static LocalAppContextSwitches()
{
IAppContextSwitchOverridesSection appContextSwitch = AppConfigManager.FetchConfigurationSection<AppContextSwitchOverridesSection>(AppContextSwitchOverridesSection.Name);
try
{
SqlAppContextSwitchManager.ApplyContextSwitches(appContextSwitch);
}
catch (Exception e)
{
// Don't throw an exception for an invalid config file
SqlClientEventSource.Log.TryTraceEvent("<sc.{0}.{1}|INFO>: {2}", TypeName, MethodBase.GetCurrentMethod().Name, e);
}
}
#endif

internal static bool IsRetryEnabled
{
get
{
if (s_isRetryEnabled is null)
{
bool result;
result = AppContext.TryGetSwitch(EnableRetryLogicSwitch, out result) ? result : false;
s_isRetryEnabled = result;
}
return s_isRetryEnabled.Value;
}
}

public static bool MakeReadAsyncBlocking
{
Expand All @@ -33,7 +68,7 @@ public static bool LegacyRowVersionNullBehavior
{
get
{
if (s_LegacyRowVersionNullBehavior == null)
if (s_LegacyRowVersionNullBehavior is null)
{
bool value = false;
if (AppContext.TryGetSwitch(LegacyRowVersionNullString, out bool providedValue))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ internal class SqlRetryLogicProvider : SqlRetryLogicBaseProvider
// keeps free RetryLogic objects
private readonly ConcurrentBag<SqlRetryLogicBase> _retryLogicPool = new ConcurrentBag<SqlRetryLogicBase>();

// safety switch for the preview version
internal const string EnableRetryLogicSwitch = "Switch.Microsoft.Data.SqlClient.EnableRetryLogic";

/// <summary>Creates an instance of this type.</summary>
public SqlRetryLogicProvider(SqlRetryLogicBase retryLogic)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,44 +9,34 @@

namespace Microsoft.Data.SqlClient
{
/// <summary>
/// Configurable retry logic manager;
/// Receive the default providers by a loader and feeds the connections and commands.
/// </summary>
internal sealed partial class SqlConfigurableRetryLogicManager
{
private static readonly Lazy<SqlConfigurableRetryLogicLoader> s_loader =
new Lazy<SqlConfigurableRetryLogicLoader>(() =>
{
ISqlConfigurableRetryConnectionSection cnnConfig = null;
ISqlConfigurableRetryCommandSection cmdConfig = null;

// Fetch the section attributes values from the configuration section of the app config file.
cnnConfig = AppConfigManager.FetchConfigurationSection<SqlConfigurableRetryConnectionSection>(SqlConfigurableRetryConnectionSection.Name);
cmdConfig = AppConfigManager.FetchConfigurationSection<SqlConfigurableRetryCommandSection>(SqlConfigurableRetryCommandSection.Name);
#if !NETFRAMEWORK
IAppContextSwitchOverridesSection appContextSwitch = AppConfigManager.FetchConfigurationSection<AppContextSwitchOverridesSection>(AppContextSwitchOverridesSection.Name);
try
{
SqlAppContextSwitchManager.ApplyContextSwitches(appContextSwitch);
}
catch (Exception e)
{
// Don't throw an exception for an invalid config file
SqlClientEventSource.Log.TryTraceEvent("<sc.{0}.{1}|INFO>: {2}", TypeName, MethodBase.GetCurrentMethod().Name, e);
}
#endif
return new SqlConfigurableRetryLogicLoader(cnnConfig, cmdConfig);
});
}

/// <summary>
/// Configurable retry logic loader
/// This class shouldn't throw exceptions;
/// All exceptions should be handled internally and logged with Event Source.
/// </summary>
internal sealed partial class SqlConfigurableRetryLogicLoader
{
private const string TypeName = nameof(SqlConfigurableRetryLogicLoader);

/// <summary>
/// The default non retry provider will apply if a parameter passes by null.
/// </summary>
private void AssignProviders(SqlRetryLogicBaseProvider cnnProvider = null, SqlRetryLogicBaseProvider cmdProvider = null)
{
ConnectionProvider = cnnProvider ?? SqlConfigurableRetryFactory.CreateNoneRetryProvider();
CommandProvider = cmdProvider ?? SqlConfigurableRetryFactory.CreateNoneRetryProvider();
}

/// <summary>
/// Default Retry provider for SqlConnections
/// </summary>
internal SqlRetryLogicBaseProvider ConnectionProvider { get; private set; }

/// <summary>
/// Default Retry provider for SqlCommands
/// </summary>
internal SqlRetryLogicBaseProvider CommandProvider { get; private set; }

public SqlConfigurableRetryLogicLoader(ISqlConfigurableRetryConnectionSection connectionRetryConfigs,
ISqlConfigurableRetryCommandSection commandRetryConfigs,
string cnnSectionName = SqlConfigurableRetryConnectionSection.Name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,23 @@ namespace Microsoft.Data.SqlClient
/// Configurable retry logic manager;
/// Receive the default providers by a loader and feeds connections and commands.
/// </summary>
internal sealed partial class SqlConfigurableRetryLogicManager
internal sealed class SqlConfigurableRetryLogicManager
{
private const string TypeName = nameof(SqlConfigurableRetryLogicManager);

private static readonly Lazy<SqlConfigurableRetryLogicLoader> s_loader =
new Lazy<SqlConfigurableRetryLogicLoader>(() =>
{
ISqlConfigurableRetryConnectionSection cnnConfig = null;
ISqlConfigurableRetryCommandSection cmdConfig = null;

// Fetch the section attributes values from the configuration section of the app config file.
cnnConfig = AppConfigManager.FetchConfigurationSection<SqlConfigurableRetryConnectionSection>(SqlConfigurableRetryConnectionSection.Name);
cmdConfig = AppConfigManager.FetchConfigurationSection<SqlConfigurableRetryCommandSection>(SqlConfigurableRetryCommandSection.Name);

return new SqlConfigurableRetryLogicLoader(cnnConfig, cmdConfig);
});

private SqlConfigurableRetryLogicManager() {/*prevent external object creation*/}

/// <summary>
Expand Down Expand Up @@ -75,33 +88,6 @@ internal static SqlRetryLogicBaseProvider CommandProvider

}

/// <summary>
/// Configurable retry logic loader
/// </summary>
internal sealed partial class SqlConfigurableRetryLogicLoader
{
private const string TypeName = nameof(SqlConfigurableRetryLogicLoader);

/// <summary>
/// The default non retry provider will apply if a parameter passes by null.
/// </summary>
private void AssignProviders(SqlRetryLogicBaseProvider cnnProvider = null, SqlRetryLogicBaseProvider cmdProvider = null)
{
ConnectionProvider = cnnProvider ?? SqlConfigurableRetryFactory.CreateNoneRetryProvider();
CommandProvider = cmdProvider ?? SqlConfigurableRetryFactory.CreateNoneRetryProvider();
}

/// <summary>
/// Default Retry provider for SqlConnections
/// </summary>
internal SqlRetryLogicBaseProvider ConnectionProvider { get; private set; }

/// <summary>
/// Default Retry provider for SqlCommands
/// </summary>
internal SqlRetryLogicBaseProvider CommandProvider { get; private set; }
}

internal interface IAppContextSwitchOverridesSection
{
string Value { get; set; }
Expand Down
Loading