Skip to content

Commit

Permalink
Add support ConfigurationManager in Net Standard for configurable ret…
Browse files Browse the repository at this point in the history
…ry logic (#1090)
  • Loading branch information
DavoudEshtehari authored Jun 7, 2021
1 parent b672ea7 commit a51a674
Show file tree
Hide file tree
Showing 18 changed files with 108 additions and 171 deletions.
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" />
<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

0 comments on commit a51a674

Please sign in to comment.