Skip to content

Commit

Permalink
Automatically adjust the default ConnectRetryCount if targeting OnDem…
Browse files Browse the repository at this point in the history
…and endpoint (#1626)
  • Loading branch information
David-Engel authored May 30, 2022
1 parent 2cfac4d commit a43348b
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -412,9 +412,15 @@ private void CacheConnectionStringProperties()
if (connString != null)
{
_connectRetryCount = connString.ConnectRetryCount;
// For Azure Synapse ondemand connections, set _connectRetryCount to 5 instead of 1 to greatly improve recovery
// success rate. Note: Synapse should be detected first as it could be detected as a regular Azure SQL DB endpoint.
if (_connectRetryCount == 1 && ADP.IsAzureSynapseOnDemandEndpoint(connString.DataSource))
{
_connectRetryCount = 5;
}
// For Azure SQL connection, set _connectRetryCount to 2 instead of 1 will greatly improve recovery
// success rate
if (_connectRetryCount == 1 && ADP.IsAzureSqlServerEndpoint(connString.DataSource))
// success rate
else if (_connectRetryCount == 1 && ADP.IsAzureSqlServerEndpoint(connString.DataSource))
{
_connectRetryCount = 2;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -432,9 +432,15 @@ private void CacheConnectionStringProperties()
if (connString != null)
{
_connectRetryCount = connString.ConnectRetryCount;
// For Azure Synapse ondemand connections, set _connectRetryCount to 5 instead of 1 to greatly improve recovery
// success rate. Note: Synapse should be detected first as it could be detected as a regular Azure SQL DB endpoint.
if (_connectRetryCount == 1 && ADP.IsAzureSynapseOnDemandEndpoint(connString.DataSource))
{
_connectRetryCount = 5;
}
// For Azure SQL connection, set _connectRetryCount to 2 instead of 1 will greatly improve recovery
// success rate
if (_connectRetryCount == 1 && ADP.IsAzureSqlServerEndpoint(connString.DataSource))
// success rate
else if (_connectRetryCount == 1 && ADP.IsAzureSqlServerEndpoint(connString.DataSource))
{
_connectRetryCount = 2;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -686,13 +686,26 @@ internal static Version GetAssemblyVersion()
}


private const string ONDEMAND_PREFIX = "-ondemand";
private const string AZURE_SYNAPSE = "-ondemand.sql.azuresynapse.";

internal static bool IsAzureSynapseOnDemandEndpoint(string dataSource)
{
return IsEndpoint(dataSource, ONDEMAND_PREFIX) || dataSource.Contains(AZURE_SYNAPSE);
}

internal static readonly string[] s_azureSqlServerEndpoints = { StringsHelper.GetString(Strings.AZURESQL_GenericEndpoint),
StringsHelper.GetString(Strings.AZURESQL_GermanEndpoint),
StringsHelper.GetString(Strings.AZURESQL_UsGovEndpoint),
StringsHelper.GetString(Strings.AZURESQL_ChinaEndpoint)};

// This method assumes dataSource parameter is in TCP connection string format.
internal static bool IsAzureSqlServerEndpoint(string dataSource)
{
return IsEndpoint(dataSource, null);
}

// This method assumes dataSource parameter is in TCP connection string format.
private static bool IsEndpoint(string dataSource, string prefix)
{
int length = dataSource.Length;
// remove server port
Expand All @@ -715,10 +728,10 @@ internal static bool IsAzureSqlServerEndpoint(string dataSource)
length -= 1;
}

// check if servername end with any azure endpoints
// check if servername ends with any endpoints
for (int index = 0; index < s_azureSqlServerEndpoints.Length; index++)
{
string endpoint = s_azureSqlServerEndpoints[index];
string endpoint = string.IsNullOrEmpty(prefix) ? s_azureSqlServerEndpoints[index] : prefix + s_azureSqlServerEndpoints[index];
if (length > endpoint.Length)
{
if (string.Compare(dataSource, length - endpoint.Length, endpoint, 0, endpoint.Length, StringComparison.OrdinalIgnoreCase) == 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Data;
using System.Collections.Generic;
using Xunit;
using System.Reflection;

namespace Microsoft.Data.SqlClient.Tests
{
Expand Down Expand Up @@ -1031,5 +1032,34 @@ public void ConnectionString_IPAddressPreference_Invalid(string value)
Assert.Contains("'ip address preference'", ex.Message, StringComparison.OrdinalIgnoreCase);
Assert.Null(ex.ParamName);
}

[Fact]
public void ConnectionRetryForNonAzureEndpoints()
{
SqlConnection cn = new SqlConnection("Data Source = someserver");
FieldInfo field = typeof(SqlConnection).GetField("_connectRetryCount", BindingFlags.Instance | BindingFlags.NonPublic);
Assert.NotNull(field.GetValue(cn));
Assert.Equal(1, (int)field.GetValue(cn));
}

[Fact]
public void ConnectionRetryForAzureDbEndpoints()
{
SqlConnection cn = new SqlConnection("Data Source = someserver.database.windows.net");
FieldInfo field = typeof(SqlConnection).GetField("_connectRetryCount", BindingFlags.Instance | BindingFlags.NonPublic);
Assert.NotNull(field.GetValue(cn));
Assert.Equal(2, (int)field.GetValue(cn));
}

[Theory]
[InlineData("myserver-ondemand.sql.azuresynapse.net")]
[InlineData("someserver-ondemand.database.windows.net")]
public void ConnectionRetryForAzureOnDemandEndpoints(string serverName)
{
SqlConnection cn = new SqlConnection($"Data Source = {serverName}");
FieldInfo field = typeof(SqlConnection).GetField("_connectRetryCount", BindingFlags.Instance | BindingFlags.NonPublic);
Assert.NotNull(field.GetValue(cn));
Assert.Equal(5, (int)field.GetValue(cn));
}
}
}

0 comments on commit a43348b

Please sign in to comment.