diff --git a/clang-tools-extra/clangd/index/remote/Client.cpp b/clang-tools-extra/clangd/index/remote/Client.cpp index 0387e65db7d026..bda3a971f418fb 100644 --- a/clang-tools-extra/clangd/index/remote/Client.cpp +++ b/clang-tools-extra/clangd/index/remote/Client.cpp @@ -19,14 +19,40 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/Error.h" +#include #include +#include namespace clang { namespace clangd { namespace remote { namespace { +llvm::StringRef toString(const grpc_connectivity_state &State) { + switch (State) { + case GRPC_CHANNEL_IDLE: + return "idle"; + case GRPC_CHANNEL_CONNECTING: + return "connecting"; + case GRPC_CHANNEL_READY: + return "ready"; + case GRPC_CHANNEL_TRANSIENT_FAILURE: + return "transient failure"; + case GRPC_CHANNEL_SHUTDOWN: + return "shutdown"; + } + llvm_unreachable("Not a valid grpc_connectivity_state."); +} + class IndexClient : public clangd::SymbolIndex { + void updateConnectionStatus() const { + auto NewStatus = Channel->GetState(/*try_to_connect=*/false); + auto OldStatus = ConnectionStatus.exchange(NewStatus); + if (OldStatus != NewStatus) + vlog("Remote index connection [{0}]: {1} => {2}", ServerAddress, + toString(OldStatus), toString(NewStatus)); + } + template using StreamingCall = std::unique_ptr> ( remote::v1::SymbolIndex::Stub::*)(grpc::ClientContext *, @@ -37,6 +63,7 @@ class IndexClient : public clangd::SymbolIndex { bool streamRPC(ClangdRequestT Request, StreamingCall RPCCall, CallbackT Callback) const { + updateConnectionStatus(); bool FinalResult = false; trace::Span Tracer(RequestT::descriptor()->name()); const auto RPCRequest = ProtobufMarshaller->toProtobuf(Request); @@ -77,18 +104,21 @@ class IndexClient : public clangd::SymbolIndex { SPAN_ATTACH(Tracer, "Status", Reader->Finish().ok()); SPAN_ATTACH(Tracer, "Successful", Successful); SPAN_ATTACH(Tracer, "Failed to parse", FailedToParse); + updateConnectionStatus(); return FinalResult; } public: IndexClient( - std::shared_ptr Channel, llvm::StringRef ProjectRoot, - llvm::StringRef Address, + std::shared_ptr Channel, llvm::StringRef Address, + llvm::StringRef ProjectRoot, std::chrono::milliseconds DeadlineTime = std::chrono::milliseconds(1000)) - : Stub(remote::v1::SymbolIndex::NewStub(Channel)), + : Stub(remote::v1::SymbolIndex::NewStub(Channel)), Channel(Channel), + ServerAddress(Address), + ConnectionStatus(Channel->GetState(/*try_to_connect=*/true)), ProtobufMarshaller(new Marshaller(/*RemoteIndexRoot=*/"", /*LocalIndexRoot=*/ProjectRoot)), - ServerAddress(Address), DeadlineWaitingTime(DeadlineTime) { + DeadlineWaitingTime(DeadlineTime) { assert(!ProjectRoot.empty()); } @@ -128,8 +158,10 @@ class IndexClient : public clangd::SymbolIndex { private: std::unique_ptr Stub; - std::unique_ptr ProtobufMarshaller; + std::shared_ptr Channel; llvm::SmallString<256> ServerAddress; + mutable std::atomic ConnectionStatus; + std::unique_ptr ProtobufMarshaller; // Each request will be terminated if it takes too long. std::chrono::milliseconds DeadlineWaitingTime; }; @@ -140,9 +172,8 @@ std::unique_ptr getClient(llvm::StringRef Address, llvm::StringRef ProjectRoot) { const auto Channel = grpc::CreateChannel(Address.str(), grpc::InsecureChannelCredentials()); - Channel->GetState(true); return std::unique_ptr( - new IndexClient(Channel, ProjectRoot, Address)); + new IndexClient(Channel, Address, ProjectRoot)); } } // namespace remote