kbobyrev created this revision. kbobyrev added a reviewer: kadircet. Herald added subscribers: cfe-commits, usaxena95, arphaman, jkorous. Herald added a project: clang. kbobyrev requested review of this revision. Herald added subscribers: MaskRay, ilya-biryukov.
This patch adds a mechanism to load new versions of index into clangd-index-server using SwapIndex and FileStatus information about last modification time without downtime. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D87450 Files: 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 @@ -14,13 +14,18 @@ #include "support/Logger.h" #include "support/Trace.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Chrono.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Error.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" #include "llvm/Support/Signals.h" +#include <chrono> #include <grpc++/grpc++.h> #include <grpc++/health_check_service_interface.h> +#include <memory> +#include <thread> #include "Index.grpc.pb.h" @@ -69,8 +74,7 @@ class RemoteIndexServer final : public SymbolIndex::Service { public: - RemoteIndexServer(std::unique_ptr<clangd::SymbolIndex> Index, - llvm::StringRef IndexRoot) + RemoteIndexServer(clangd::SwapIndex *Index, llvm::StringRef IndexRoot) : Index(std::move(Index)) { llvm::SmallString<256> NativePath = IndexRoot; llvm::sys::path::native(NativePath); @@ -79,6 +83,8 @@ /*LocalIndexRoot=*/"")); } + clangd::SwapIndex *Index; + private: grpc::Status Lookup(grpc::ServerContext *Context, const LookupRequest *Request, @@ -210,21 +216,52 @@ return grpc::Status::OK; } - std::unique_ptr<clangd::SymbolIndex> Index; std::unique_ptr<Marshaller> ProtobufMarshaller; }; -void runServer(std::unique_ptr<clangd::SymbolIndex> Index, - const std::string &ServerAddress) { - RemoteIndexServer Service(std::move(Index), IndexRoot); +// Detect changes in \p IndexPath file and load new versions of the index +// whenever they become available. +void hotReload(clangd::SwapIndex **Index, llvm::StringRef IndexPath) { + llvm::sys::TimePoint<> LastModificationTime = + std::chrono::system_clock::now(); + for (;; std::this_thread::sleep_for(std::chrono::seconds(90))) { + llvm::sys::fs::file_status Status; + const auto EC = llvm::sys::fs::status(IndexPath, Status, /*Follow=*/true); + if (EC) + continue; + const auto NewModificationTime = Status.getLastModificationTime(); + // Current index is newer than the one before: no reload is needed. + if (NewModificationTime <= LastModificationTime) + continue; + vlog("Found new index version: existing index was modified at {0}, new " + "index was modified at {1}. Attempting to reload.", + LastModificationTime, NewModificationTime); + std::unique_ptr<clang::clangd::SymbolIndex> NewIndex = openIndex(IndexPath); + if (!NewIndex) { + vlog("Failed to load new index. Old index will be served."); + continue; + } + (*Index)->reset(std::move(NewIndex)); + log("New index version loaded. Last modification time: {0}.", + NewModificationTime); + LastModificationTime = NewModificationTime; + } +} + +void runServer(std::unique_ptr<clangd::SwapIndex> Index, + llvm::StringRef ServerAddress, llvm::StringRef IndexPath) { + RemoteIndexServer Service(Index.get(), IndexRoot); grpc::EnableDefaultHealthCheckService(true); grpc::ServerBuilder Builder; - Builder.AddListeningPort(ServerAddress, grpc::InsecureServerCredentials()); + Builder.AddListeningPort(ServerAddress.str(), + grpc::InsecureServerCredentials()); Builder.RegisterService(&Service); std::unique_ptr<grpc::Server> Server(Builder.BuildAndStart()); log("Server listening on {0}", ServerAddress); + std::thread HotReloadThread(hotReload, &Service.Index, IndexPath); + Server->Wait(); } @@ -273,12 +310,13 @@ if (Tracer) TracingSession.emplace(*Tracer); - std::unique_ptr<clang::clangd::SymbolIndex> Index = openIndex(IndexPath); + std::unique_ptr<clang::clangd::SwapIndex> Index( + new clang::clangd::SwapIndex(openIndex(IndexPath))); if (!Index) { llvm::errs() << "Failed to open the index.\n"; return -1; } - runServer(std::move(Index), ServerAddress); + runServer(std::move(Index), ServerAddress, IndexPath); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits