grpc WriteAsync正在锁定服务器



Grpc.Core 2.38.0

我有一组应用程序,它们使用grpc流参与进程间通信。我们不时注意到服务器进程中的锁定和内存耗尽(由于锁定)无法完成对IAsyncStreamWriter.WriteAsync(...)的调用

最近对grpc(.net)的更改已将WriteAsyncAPI更改为接受CancellationToken,但这在Grpc.Core包中不可用。

错误配置的grpc客户端接受流可能会导致死锁。如果客户端在错误处理期间不处理AsyncServerStreamingCall,则服务器上将发生死锁。

示例:

async Task ClientStreamingThread()
{
while (...)
{
var theStream = grpcService.SomeStream(new());
try
{
while (await theStream.ResponseStream.MoveNext(shutdownToken.Token))
{
var theData = theStream.ResponseStream.Current;
}
}
catch (RpcException)
{
// if an exception occurs, start over, reopen the stream
}
}
}

上面的示例包含行为不端的客户端。如果出现RpcException,我们将返回while循环的开始,并打开另一个流,而不清理前一个流。这导致了死锁。

"修复";客户端代码,通过像下面这样处理前一个流:

async Task ClientStreamingThread()
{
while (...)
{
// important.  dispose of theStream if it goes out of scope
using var theStream = grpcService.SomeStream(new());
try
{
while (await theStream.ResponseStream.MoveNext(shutdownToken.Token))
{
var theData = theStream.ResponseStream.Current;
}
}
catch (RpcException)
{
// if an exception occurs, start over, reopen the stream
}
}
}

最新更新