Datastax C#驱动程序3.3.0连接到群集时发生死锁?
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运行相同的测试没有这样的问题。任何人都可以测试这个吗?也许这只是发生在我身上。
编辑:
这里是僵局的截图:
感谢您的意见中的细节,我们能够确定潜在的问题。
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
你可以预期修补程序将在下一个修补程序版本中着陆。
我不能重现该问题,但我怀疑问题可能是一个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上打开一个问题。
希望有帮助!
仍遇到问题。我没有使用JIRA的经验,所以我不确定在那里发布什么和如何发布。我会继续在这里和github发帖。 –
此驱动程序的JIRA可以在这里找到:https://datastax-oss.atlassian.net/projects/CSHARP/summary 它需要一个简单的帐户设置来创建一张票。 –
问题已经在这里开幕的解决方法:
https://datastax-oss.atlassian.net/projects/CSHARP/issues/CSHARP-579
对于任何人遇到了相同的 - 只是包装你的连接代码到一个新的任务。
Task.Run(() =>
{
SimpleConnectTest();
});
该驱动程序的3.3.1版本已针对此问题进行了修复。 –
这是在控制台应用程序? Web应用程序? Web表单应用程序? –
这发生在Windows窗体应用程序,Windows服务和IIS应用程序上。所有在Windows Server 2012 R2上运行。还在我的本地机器上使用Windows 10对其进行了测试。所有内容均针对.NET Framework 4.5.2编写。 –
从你的解释中,你所遇到的并不是死锁:调用线程永远不会被阻塞(很久以后它会抛出一个异常)。要理解底下发生了什么,应该启用[驱动程序日志记录](http://docs.datastax.com/en/developer/csharp-driver/3.3/faq/#how-can-i-enable-logging-在最驱动程序)。 – jorgebg