Hi, everyone!
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.
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, but grpc::ClientContext::set_fail_fast(bool) method is DEPRECATED. It's recommended to use wait_for_ready(). Is it true that in the future set_wait_for_ready should become a replacement set_fail_fast?
- Are there any other ways to solve this problem? I was also looking at ChannelState API https://chromium.googlesource.com/external/github.com/grpc/grpc/+/refs/heads/chromium-deps/2016-09-09/doc/connectivity-semantics-and-api.md 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.
Thank you for your time.
Highly appreciated.
Sergey