I'm writing test (with gtest) with grpc similar to the following (in C++ pseudocode):
class Fixture {
void SetUp() { m_server = BuildAndStart(); }
void TearDown() { m_server->Shutdown(); }
};
TEST_F(Fixture, Test1) { ASSERT_EQ(clientStub->rpcCall(ctx), grpc::Status::OK); }
TEST_F(Fixture, Test2) { ASSERT_EQ(clientStub->rpcCall(ctx), grpc::Status::OK); }
When compiling (clang++11) with a thread sanitizer (grpc library compiling with tsan too) sometimes I get an error UNAVALABLE (code 14) with logs: "Failed to pick subchannel", "Failed to connect to all addresses" and observe the state of the channel is TRANSIENT_FAILURE.
But only the first test always fails (Test1). Searching the internet I found the following suitable solution
In other words, with tsan I guess grpc library does not have enough time to fully initialize (Test2 is always OK). After use grpc::ClientContext::set_wait_for_ready(bool) method problem solved
TEST_F(Fixture, Test1) { ASSERT_EQ(clientStub->rpcCall(ctxWithWait), grpc::Status::OK); }
TEST_F(Fixture, Test2) { ASSERT_EQ(clientStub->rpcCall(ctxWithWait), grpc::Status::OK); }
My questions are:
grpc::ClientContext::set_wait_for_ready(bool)marked as EXPERIMENTAL (C++ api) and may be removed in the future, butgrpc::ClientContext::set_fail_fast(bool)method is DEPRECATED. It's recommended to usewait_for_ready(). Is it true that in the futureset_wait_for_readyshould become a replacementset_fail_fast?- Are there any other ways to solve this problem? I was also looking at ChannelState API method
bool grpc::ChannelInterface::WaitForConnected(T deadline). Which way is more correct and reliable?
I will also need to implement similar logic in C# code. In C# this is a CallOptions.WithWaitForReady(bool) method, but it's EXPERIMENTAL too
Wished to clear up a misunderstanding and choose the right solution.