Skip to content

Azure SQL DB connection hangs with zero-connection timeout  #58

@MaximLipnin

Description

@MaximLipnin

From mono/mono#13065

There is an issue when a connection to Azure SQL DB hangs on macOS if connection string contains Connection Timeout=0.

My repro sample is:

using System;
using System.Data.SqlClient;

namespace MyTest
{
    public class Repro
    {
        public static void Main()
        {
            OpenSqlConnection();
        }

        private static void OpenSqlConnection()
        {
            string connectionString = GetConnectionString();
            using (SqlConnection connection = new SqlConnection())
            {
                connection.ConnectionString = connectionString;
                connection.Open();
                Console.WriteLine("State: {0}", connection.State);
                Console.WriteLine("ConnectionString: {0}",  connection.ConnectionString);
            }
        }

        static private string GetConnectionString()
        {
            return "<some connection string stuff>;Connection Timeout=0;";
        }
    }
}

It's reproducible with Mono version which uses System.Data.SqlClient namespace from CoreFX. But there is no repro with Net Core 2.2.

It looks like it makes attempts to login and fails with System.ObjectDisposedException exception which is not the reason correctly to break login loop.

It occurs in non-parallel conditional branch of SNITCPHandle ctor:
https://github.com/dotnet/corefx/blob/master/src/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNITcpHandle.cs#L145

Further in case of zero timeout Cancel callback might be invoked (and dispose socket) before Socket.Connect:
https://github.com/dotnet/corefx/blob/master/src/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNITcpHandle.cs#L200-L216

Possible fix is to pass infinite timeout to Connect method https://github.com/dotnet/corefx/blob/master/src/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNITcpHandle.cs#L145:

_socket = Connect(serverName, port, isInfiniteTimeOut ? TimeSpan.FromMilliseconds(Int32.MaxValue) : ts);

Does it make sense for you?

/cc @afsanehr @marek-safar

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions