2017-06-13 70 views
2

To Datastax C#驱动程序工程师:Datastax C#驱动程序3.3.0连接到群集时发生死锁?

C#驱动程序3.3.0在致电Connect()时死锁。在Windows窗体下面的代码片段将僵局尝试连接:

public void SimpleConnectTest() 
    { 
     const string ip = "127.0.0.1"; 
     const string keyspace = "somekeyspace"; 

     QueryOptions queryOptions = new QueryOptions(); 
     queryOptions.SetConsistencyLevel(ConsistencyLevel.One); 

     Cluster cluster = Cluster.Builder() 
      .AddContactPoints(ip) 
      .WithQueryOptions(queryOptions) 
      .Build(); 

     var cassandraSession = cluster.Connect(keyspace); 

     Assert.AreNotEqual(null, cassandraSession); 

     cluster.Dispose(); 
    } 

死锁发生在这里:

Cluster.cs -> 
private void Init() 
{ 
    ... 
TaskHelper.WaitToComplete(_controlConnection.Init(), initialAbortTimeout); 
    ... 
} 

我已经在本地机器上的卡桑德拉3.9.0测试此,CQL规范3.4.2。在调用此方法_controlConnection.Init()

一切死锁在这里:

task = Id = 11, Status = WaitingForActivation, Method = "{null}", Result = "{Not yet computed}" 

这然后就运行了30000ms,并抛出这样的:

   throw new TimeoutException(
        "Cluster initialization was aborted after timing out. This mechanism is put in place to" + 
        " avoid blocking the calling thread forever. This usually caused by a networking issue" + 
        " between the client driver instance and the cluster.", ex); 

在3.2.0运行相同的测试没有这样的问题。任何人都可以测试这个吗?也许这只是发生在我身上。

编辑:

这里是僵局的截图:

Deadlocked tasks with blocking awaiting()

+1

这是在控制台应用程序? Web应用程序? Web表单应用程序? –

+0

这发生在Windows窗体应用程序,Windows服务和IIS应用程序上。所有在Windows Server 2012 R2上运行。还在我的本地机器上使用Windows 10对其进行了测试。所有内容均针对.NET Framework 4.5.2编写。 –

+0

从你的解释中,你所遇到的并不是死锁:调用线程永远不会被阻塞(很久以后它会抛出一个异常)。要理解底下发生了什么,应该启用[驱动程序日志记录](http://docs.datastax.com/en/developer/csharp-driver/3.3/faq/#how-can-i-enable-logging-在最驱动程序)。 – jorgebg

回答

2

感谢您的意见中的细节,我们能够确定潜在的问题。

Similar to what was proposed by Luke,有一些失踪ConfigureAwait()调用。

这个问题正在呼吁环境Cluster.Connect()SynchonizationContext影响用户这是不常见的用例:

  • 对于Windows窗体,它不可能直接传送到数据库中(无需中间服务) 。此外,用户应在创建表单之前调用Connect()(其中没有SynchonizationContext)以在所有表​​单上共享同一个Session实例。
  • 对于ASP.NET,在创建HttpContext(没有SynchonizationContext)之前,用户应在任何端点操作之外调用Connect()

请注意,此问题仅影响Connect()调用。其他阻止呼叫如Execute()不存在此问题。

在任何情况下,这个问题都可能成为用户开始使用驱动程序的炫目者,例如,用户创建一个简单的Windows窗体应用程序来尝试一个概念。

我已经提交pull请求与修订,其中也包含了测试,看起来成的await使用的源代码,而不ConfigureAwait()调用,以避免以后发生这种问题: https://github.com/datastax/csharp-driver/pull/309

你可以预期修补程序将在下一个修补程序版本中着陆。

1

我不能重现该问题,但我怀疑问题可能是一个recent change,使连接过程内部异步。我不知道,但通过Connect代码追查,我怀疑它可能是一个失踪ConfigureAwait(false)。特别是,它看起来像Reconnect方法(它肯定可以作为Init代码路径的一部分)is missing one after that commit。有可能我无法复制它,因为我没有击中Reconnect代码路径,而出于某种原因,您处于您的环境中。

我不是100%确定这是罪魁祸首,但我需要opened a PR来修复它。 Stephen Cleary写了一个great explanation为什么这可能发生在Forms/Web应用程序中。您可以尝试从我的分支中构建驱动程序,以查看此更改是否解决了问题,或者等待并看看PR和新版本会发生什么情况。如果还在发生,我建议在JIRA上打开一个问题。

希望有帮助!

+0

仍遇到问题。我没有使用JIRA的经验,所以我不确定在那里发布什么和如何发布。我会继续在这里和github发帖。 –

+0

此驱动程序的JIRA可以在这里找到:https://datastax-oss.atlassian.net/projects/CSHARP/summary 它需要一个简单的帐户设置来创建一张票。 –