kbobyrev updated this revision to Diff 307942. kbobyrev added a comment. This is working now. However, the handshake is actually deferred for ProjectAwareIndex until the first request. I tried to invoke it via something like `Opts.StaticIdx->estimateMemoryUsage()` in `ClangdMain.cpp` but the problem is `getIndex()` will return `nullptr` until the `Config::current` is ready. I'm not entirely sure when this happens so I can't promote handshake to some sensible time point yet.
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D92198/new/ https://reviews.llvm.org/D92198 Files: clang-tools-extra/clangd/index/remote/Client.cpp clang-tools-extra/clangd/index/remote/Client.h clang-tools-extra/clangd/index/remote/Index.proto clang-tools-extra/clangd/index/remote/Service.proto clang-tools-extra/clangd/index/remote/server/Server.cpp
Index: clang-tools-extra/clangd/index/remote/server/Server.cpp =================================================================== --- clang-tools-extra/clangd/index/remote/server/Server.cpp +++ clang-tools-extra/clangd/index/remote/server/Server.cpp @@ -32,6 +32,7 @@ #include <chrono> #include <grpc++/grpc++.h> #include <grpc++/health_check_service_interface.h> +#include <grpcpp/impl/codegen/server_context.h> #include <memory> #include <thread> @@ -96,6 +97,19 @@ private: using stopwatch = std::chrono::steady_clock; + grpc::Status Handshake(grpc::ServerContext *Context, + const remote::HandshakeRequest *Request, + HandshakeReply *Reply) override { + WithContextValue WithRequestContext(CurrentRequest, Context); + logRequest(*Request); + trace::Span Tracer("LookupRequest"); + Reply->set_checksum(Request->checksum()); + logResponse(*Reply); + log("[public] request {0} => OK", HandshakeRequest::descriptor()->name()); + SPAN_ATTACH(Tracer, "Checksum", Reply->checksum()); + return grpc::Status::OK; + } + grpc::Status Lookup(grpc::ServerContext *Context, const LookupRequest *Request, grpc::ServerWriter<LookupReply> *Reply) override { Index: clang-tools-extra/clangd/index/remote/Service.proto =================================================================== --- clang-tools-extra/clangd/index/remote/Service.proto +++ clang-tools-extra/clangd/index/remote/Service.proto @@ -15,6 +15,8 @@ // Semantics of SymbolIndex match clangd::SymbolIndex with all required // structures corresponding to their clangd::* counterparts. service SymbolIndex { + rpc Handshake(HandshakeRequest) returns (HandshakeReply) {} + rpc Lookup(LookupRequest) returns (stream LookupReply) {} rpc FuzzyFind(FuzzyFindRequest) returns (stream FuzzyFindReply) {} Index: clang-tools-extra/clangd/index/remote/Index.proto =================================================================== --- clang-tools-extra/clangd/index/remote/Index.proto +++ clang-tools-extra/clangd/index/remote/Index.proto @@ -10,6 +10,14 @@ package clang.clangd.remote; +message HandshakeRequest { + required uint32 checksum = 1; +} + +message HandshakeReply { + required uint32 checksum = 1; +} + // Common final result for streaming requests. message FinalResult { optional bool has_more = 1; } Index: clang-tools-extra/clangd/index/remote/Client.h =================================================================== --- clang-tools-extra/clangd/index/remote/Client.h +++ clang-tools-extra/clangd/index/remote/Client.h @@ -22,10 +22,13 @@ /// described by the remote index. Paths returned by the index will be treated /// as relative to this directory. /// -/// This method attempts to resolve the address and establish the connection. +/// This method attempts to resolve the address and establish the connection by +/// performing the handshake (sending the data and trying to receive it back). /// -/// \returns nullptr if the address is not resolved during the function call or -/// if the project was compiled without Remote Index support. +/// \returns nullptr if one of the following conditions holds: +/// * Address is not resolved during the function call. +/// * Handshake was not successful or received data is corrupted. +/// * Project was compiled without Remote Index support. std::unique_ptr<clangd::SymbolIndex> getClient(llvm::StringRef Address, llvm::StringRef IndexRoot); Index: clang-tools-extra/clangd/index/remote/Client.cpp =================================================================== --- clang-tools-extra/clangd/index/remote/Client.cpp +++ clang-tools-extra/clangd/index/remote/Client.cpp @@ -14,11 +14,14 @@ #include "marshalling/Marshalling.h" #include "support/Logger.h" #include "support/Trace.h" +#include "clang/Basic/LLVM.h" #include "clang/Basic/Version.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Error.h" #include <chrono> +#include <cstdint> +#include <memory> namespace clang { namespace clangd { @@ -82,6 +85,35 @@ assert(!ProjectRoot.empty()); } + // Returns true if received checksum matches given one. + bool handshake(uint32_t Checksum) const { + trace::Span Tracer(HandshakeRequest::descriptor()->name()); + HandshakeRequest RPCRequest; + RPCRequest.set_checksum(Checksum); + SPAN_ATTACH(Tracer, "Request", RPCRequest.DebugString()); + grpc::ClientContext Context; + Context.AddMetadata("version", clang::getClangToolFullVersion("clangd")); + const std::chrono::system_clock::time_point StartTime = + std::chrono::system_clock::now(); + const auto Deadline = StartTime + DeadlineWaitingTime; + Context.set_deadline(Deadline); + vlog("Sending RPC Request {0}: {1}", HandshakeRequest::descriptor()->name(), + RPCRequest.DebugString()); + HandshakeReply Reply; + const grpc::Status Status = + Stub.get()->Handshake(&Context, RPCRequest, &Reply); + assert(Checksum == Reply.checksum() && "Received checksum should match."); + const auto Millis = std::chrono::duration_cast<std::chrono::milliseconds>( + std::chrono::system_clock::now() - StartTime) + .count(); + const std::string ChecksumMatches = + Checksum == Reply.checksum() ? "OK" : "CHECKSUM MISMATCH"; + vlog("RPC {0} => {1}: {2}ms", HandshakeRequest::descriptor()->name(), + ChecksumMatches, Reply.checksum(), Millis); + SPAN_ATTACH(Tracer, "Status", Status.ok()); + return Status.ok() && Checksum == Reply.checksum(); + } + void lookup(const clangd::LookupRequest &Request, llvm::function_ref<void(const clangd::Symbol &)> Callback) const override { @@ -130,8 +162,15 @@ const auto Channel = grpc::CreateChannel(Address.str(), grpc::InsecureChannelCredentials()); Channel->GetState(true); - return std::unique_ptr<clangd::SymbolIndex>( - new IndexClient(Channel, ProjectRoot)); + auto *Idx = new IndexClient(Channel, ProjectRoot); + const uint32_t Checksum = 42; + const bool OK = Idx->handshake(Checksum); + if (!OK) { + elog("Handshake did not finish correctly. Breaking the connection to " + "remote index."); + return nullptr; + } + return std::unique_ptr<SymbolIndex>(Idx); } } // namespace remote
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits