kbobyrev updated this revision to Diff 280381. kbobyrev added a comment. Abstract out the client request into a single function call.
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D84499/new/ https://reviews.llvm.org/D84499 Files: clang-tools-extra/clangd/index/remote/Client.cpp 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 @@ -8,7 +8,10 @@ #include "index/Index.h" #include "index/Serialization.h" +#include "index/Symbol.h" #include "index/remote/marshalling/Marshalling.h" +#include "support/Logger.h" +#include "support/Trace.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Path.h" @@ -16,6 +19,7 @@ #include <grpc++/grpc++.h> #include <grpc++/health_check_service_interface.h> +#include <type_traits> #include "Index.grpc.pb.h" @@ -35,6 +39,16 @@ llvm::cl::opt<std::string> IndexRoot(llvm::cl::desc("<PROJECT ROOT>"), llvm::cl::Positional, llvm::cl::Required); +llvm::cl::opt<std::string> TracerFile( + "tracer-file", + llvm::cl::desc("Path to the file where tracer logs will be stored")); + +llvm::cl::opt<bool> PrettyPrint{ + "pretty", + llvm::cl::desc("Pretty-print JSON output"), + llvm::cl::init(true), +}; + llvm::cl::opt<std::string> ServerAddress( "server-address", llvm::cl::init("0.0.0.0:50051"), llvm::cl::desc("Address of the invoked server. Defaults to 0.0.0.0:50051")); @@ -56,24 +70,52 @@ } private: + template <typename RequestT, typename ReplyT, typename ClangdRequestT, + typename IndexCall, typename StreamType, typename CallbackT> + typename std::result_of<IndexCall(clangd::SymbolIndex &, + const ClangdRequestT &, CallbackT)>::type + streamRPC(const RequestT *Request, grpc::ServerWriter<ReplyT> *Reply, + ClangdRequestT ClangdRequest, IndexCall &&Call) { + trace::Span Tracer(RequestT::descriptor()->name()); + SPAN_ATTACH(Tracer, "Request", Request->DebugString()); + unsigned Sent = 0; + unsigned FailedToSend = 0; + SPAN_ATTACH(Tracer, "Sent", Sent); + SPAN_ATTACH(Tracer, "Failed to send", FailedToSend); + return std::forward<IndexCall>(Call)( + *Index, ClangdRequest, [&](const StreamType &Item) { + auto SerializedItem = ProtobufMarshaller->toProtobuf(Item); + if (!SerializedItem) { + ++FailedToSend; + return; + } + ReplyT NextMessage; + *NextMessage.mutable_stream_result() = *SerializedItem; + Reply->Write(NextMessage); + ++Sent; + }); + } + grpc::Status Lookup(grpc::ServerContext *Context, const LookupRequest *Request, grpc::ServerWriter<LookupReply> *Reply) override { clangd::LookupRequest Req; for (const auto &ID : Request->ids()) { auto SID = SymbolID::fromStr(StringRef(ID)); - if (!SID) + if (!SID) { + elog("Lookup request cancelled: invalid SymbolID {1}", SID.takeError()); return grpc::Status::CANCELLED; + } Req.IDs.insert(*SID); } - Index->lookup(Req, [&](const clangd::Symbol &Sym) { - auto SerializedSymbol = ProtobufMarshaller->toProtobuf(Sym); - if (!SerializedSymbol) - return; - LookupReply NextMessage; - *NextMessage.mutable_stream_result() = *SerializedSymbol; - Reply->Write(NextMessage); - }); + std::function<void(clang::clangd::SymbolIndex &, + const clang::clangd::LookupRequest &, + llvm::function_ref<void(const clangd::Symbol &)>)> + IndexCall = &clangd::SymbolIndex::lookup; + streamRPC<LookupRequest, LookupReply, clangd::LookupRequest, + decltype(IndexCall), clangd::Symbol, + llvm::function_ref<void(const clangd::Symbol &)>>( + Request, Reply, Req, std::move(IndexCall)); LookupReply LastMessage; LastMessage.set_final_result(true); Reply->Write(LastMessage); @@ -83,15 +125,18 @@ grpc::Status FuzzyFind(grpc::ServerContext *Context, const FuzzyFindRequest *Request, grpc::ServerWriter<FuzzyFindReply> *Reply) override { + trace::Span Tracer("FuzzyFind"); + SPAN_ATTACH(Tracer, "Request", Request->DebugString()); const auto Req = ProtobufMarshaller->fromProtobuf(Request); - bool HasMore = Index->fuzzyFind(Req, [&](const clangd::Symbol &Sym) { - auto SerializedSymbol = ProtobufMarshaller->toProtobuf(Sym); - if (!SerializedSymbol) - return; - FuzzyFindReply NextMessage; - *NextMessage.mutable_stream_result() = *SerializedSymbol; - Reply->Write(NextMessage); - }); + std::function<bool(clang::clangd::SymbolIndex &, + const clang::clangd::FuzzyFindRequest &, + llvm::function_ref<void(const clangd::Symbol &)>)> + IndexCall = &clangd::SymbolIndex::fuzzyFind; + bool HasMore = + streamRPC<FuzzyFindRequest, FuzzyFindReply, clangd::FuzzyFindRequest, + decltype(IndexCall), clangd::Symbol, + llvm::function_ref<void(const clangd::Symbol &)>>( + Request, Reply, Req, std::move(IndexCall)); FuzzyFindReply LastMessage; LastMessage.set_final_result(HasMore); Reply->Write(LastMessage); @@ -103,18 +148,20 @@ clangd::RefsRequest Req; for (const auto &ID : Request->ids()) { auto SID = SymbolID::fromStr(StringRef(ID)); - if (!SID) + if (!SID) { + elog("Refs request cancelled: invalid SymbolID {1}", SID.takeError()); return grpc::Status::CANCELLED; + } Req.IDs.insert(*SID); } - bool HasMore = Index->refs(Req, [&](const clangd::Ref &Reference) { - auto SerializedRef = ProtobufMarshaller->toProtobuf(Reference); - if (!SerializedRef) - return; - RefsReply NextMessage; - *NextMessage.mutable_stream_result() = *SerializedRef; - Reply->Write(NextMessage); - }); + std::function<bool(clang::clangd::SymbolIndex &, + const clang::clangd::RefsRequest &, + llvm::function_ref<void(const clangd::Ref &)>)> + IndexCall = &clangd::SymbolIndex::refs; + bool HasMore = streamRPC<RefsRequest, RefsReply, clangd::RefsRequest, + decltype(IndexCall), clangd::Ref, + llvm::function_ref<void(const clangd::Ref &)>>( + Request, Reply, Req, std::move(IndexCall)); RefsReply LastMessage; LastMessage.set_final_result(HasMore); Reply->Write(LastMessage); @@ -154,6 +201,29 @@ return -1; } + llvm::Optional<llvm::raw_fd_ostream> TracerStream; + std::unique_ptr<clang::clangd::trace::EventTracer> Tracer; + if (!TracerFile.empty()) { + std::error_code EC; + TracerStream.emplace(TracerFile, EC, + llvm::sys::fs::FA_Read | llvm::sys::fs::FA_Write); + if (EC) { + TracerStream.reset(); + llvm::errs() << "Error while opening trace file " << TracerFile << ": " + << EC.message(); + } else { + // FIXME(kirillbobyrev): Also create metrics tracer to track latency and + // accumulate other request statistics. + Tracer = + clang::clangd::trace::createJSONTracer(*TracerStream, PrettyPrint); + llvm::outs() << "Successfully created a tracer.\n"; + } + } + + llvm::Optional<clang::clangd::trace::Session> TracingSession; + if (Tracer) + TracingSession.emplace(*Tracer); + std::unique_ptr<clang::clangd::SymbolIndex> Index = openIndex(IndexPath); if (!Index) { 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 @@ -37,12 +37,15 @@ bool FinalResult = false; trace::Span Tracer(RequestT::descriptor()->name()); const auto RPCRequest = ProtobufMarshaller->toProtobuf(Request); + SPAN_ATTACH(Tracer, "Request", RPCRequest.DebugString()); grpc::ClientContext Context; std::chrono::system_clock::time_point Deadline = std::chrono::system_clock::now() + DeadlineWaitingTime; Context.set_deadline(Deadline); auto Reader = (Stub.get()->*RPCCall)(&Context, RPCRequest); ReplyT Reply; + unsigned Received = 0; + unsigned FailedToParse = 0; while (Reader->Read(&Reply)) { if (!Reply.has_stream_result()) { FinalResult = Reply.final_result(); @@ -51,11 +54,15 @@ auto Response = ProtobufMarshaller->fromProtobuf(Reply.stream_result()); if (!Response) { elog("Received invalid {0}", ReplyT::descriptor()->name()); + ++FailedToParse; continue; } Callback(*Response); + ++Received; } - SPAN_ATTACH(Tracer, "status", Reader->Finish().ok()); + SPAN_ATTACH(Tracer, "Status", Reader->Finish().ok()); + SPAN_ATTACH(Tracer, "Received", Received); + SPAN_ATTACH(Tracer, "Failed to parse", FailedToParse); return FinalResult; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits