Skip to content

Commit

Permalink
[Release 1.1] Revert ReadAsync changes that caused issues (#550)
Browse files Browse the repository at this point in the history
  • Loading branch information
cheenamalhotra authored May 4, 2020
1 parent bfe3155 commit a469c15
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2756,6 +2756,12 @@ private bool TryProcessDone(SqlCommand cmd, SqlDataReader reader, ref RunBehavio
ushort status;
int count;

// This is added back since removing it from here introduces regressions in Managed SNI.
// It forces SqlDataReader.ReadAsync() method to run synchronously,
// and will block the calling thread until data is fed from SQL Server.
// TODO Investigate better solution to support non-blocking ReadAsync().
stateObj._syncOverAsync = true;

// status
// command
// rowcount (valid only if DONE_COUNT bit is set)
Expand Down Expand Up @@ -2855,11 +2861,10 @@ private bool TryProcessDone(SqlCommand cmd, SqlDataReader reader, ref RunBehavio
}
}

// _attentionSent set by 'SendAttention'
// _pendingData set by e.g. 'TdsExecuteSQLBatch'
// _hasOpenResult always set to true by 'WriteMarsHeader'
// HasPendingData set by e.g. 'TdsExecuteSQLBatch'
// HasOpenResult always set to true by 'WriteMarsHeader'
//
if (!stateObj._attentionSent && !stateObj.HasPendingData && stateObj.HasOpenResult)
if (!stateObj.HasPendingData && stateObj.HasOpenResult)
{
/*
Debug.Assert(!((sqlTransaction != null && _distributedTransaction != null) ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3324,11 +3324,10 @@ private bool TryProcessDone(SqlCommand cmd, SqlDataReader reader, ref RunBehavio
}
}

// _attentionSent set by 'SendAttention'
// _pendingData set by e.g. 'TdsExecuteSQLBatch'
// _hasOpenResult always set to true by 'WriteMarsHeader'
//
if (!stateObj._attentionSent && !stateObj._pendingData && stateObj._hasOpenResult)
if (!stateObj._pendingData && stateObj._hasOpenResult)
{
/*
Debug.Assert(!((sqlTransaction != null && _distributedTransaction != null) ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,92 @@ public static void TimeOutDuringRead()
TimeOutDuringRead(s_connStr);
}

[CheckConnStrSetupFact]
public static void TCPAttentionPacketTestTransaction()
{
CancelFollowedByTransaction(s_connStr);
}

[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureServer))]
public static void TCPAttentionPacketTestAlerts()
{
CancelFollowedByAlert(s_connStr);
}

private static void CancelFollowedByTransaction(string constr)
{
using (SqlConnection connection = new SqlConnection(constr))
{
connection.Open();
using (SqlCommand cmd = connection.CreateCommand())
{
cmd.CommandText = @"SELECT @@VERSION";
using (var r = cmd.ExecuteReader())
{
cmd.Cancel();
}
}
using (SqlTransaction transaction = connection.BeginTransaction())
{ }
}
}

private static void CancelFollowedByAlert(string constr)
{
var alertName = "myAlert" + Guid.NewGuid().ToString();
// Since Alert conditions are randomly generated,
// we will retry on unexpected error messages to avoid collision in pipelines.
var n = new Random().Next(1, 100);
bool retry = true;
int retryAttempt = 0;
while (retry && retryAttempt < 3)
{
try
{
using (var conn = new SqlConnection(constr))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "SELECT @@VERSION";
using (var reader = cmd.ExecuteReader())
{
cmd.Cancel(); // Sends Attention
}
}
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = $@"EXEC msdb.dbo.sp_add_alert @name=N'{alertName}',
@performance_condition = N'SQLServer:General Statistics|User Connections||>|{n}'";
cmd.ExecuteNonQuery();
cmd.CommandText = @"USE [msdb]";
cmd.ExecuteNonQuery();
cmd.CommandText = $@"/****** Object: Alert [{alertName}] Script Date: {DateTime.Now} ******/
IF EXISTS (SELECT name FROM msdb.dbo.sysalerts WHERE name = N'{alertName}')
EXEC msdb.dbo.sp_delete_alert @name=N'{alertName}'";
cmd.ExecuteNonQuery();
}
}
}
catch (Exception e)
{
if (retryAttempt >= 3 || e.Message.Contains("The transaction operation cannot be performed"))
{
Assert.False(true, $"Retry Attempt: {retryAttempt} | Unexpected Exception occurred: {e.Message}");
}
else
{
retry = true;
retryAttempt++;
Console.WriteLine($"CancelFollowedByAlert Test retry attempt : {retryAttempt}");
Thread.Sleep(500);
continue;
}
}
retry = false;
}
}

private static void MultiThreadedCancel(string constr, bool async)
{
using (SqlConnection con = new SqlConnection(constr))
Expand Down

0 comments on commit a469c15

Please sign in to comment.