kbobyrev updated this revision to Diff 291521.
kbobyrev marked 2 inline comments as done.
kbobyrev added a comment.
Address remaining comments.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D87450/new/
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
@@ -12,15 +12,24 @@
#include "index/Symbol.h"
#include "index/remote/marshalling/Marshalling.h"
#include "support/Logger.h"
+#include "support/Shutdown.h"
+#include "support/ThreadsafeFS.h"
#include "support/Trace.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.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 "llvm/Support/VirtualFileSystem.h"
+#include <chrono>
#include <grpc++/grpc++.h>
#include <grpc++/health_check_service_interface.h>
+#include <memory>
+#include <thread>
#include "Index.grpc.pb.h"
@@ -63,15 +72,10 @@
"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"));
-std::unique_ptr<clangd::SymbolIndex> openIndex(llvm::StringRef Index) {
- return loadIndex(Index, /*UseIndex=*/true);
-}
-
class RemoteIndexServer final : public SymbolIndex::Service {
public:
- RemoteIndexServer(std::unique_ptr<clangd::SymbolIndex> Index,
- llvm::StringRef IndexRoot)
- : Index(std::move(Index)) {
+ RemoteIndexServer(clangd::SymbolIndex &Index, llvm::StringRef IndexRoot)
+ : Index(Index) {
llvm::SmallString<256> NativePath = IndexRoot;
llvm::sys::path::native(NativePath);
ProtobufMarshaller = std::unique_ptr<Marshaller>(new Marshaller(
@@ -91,7 +95,7 @@
}
unsigned Sent = 0;
unsigned FailedToSend = 0;
- Index->lookup(*Req, [&](const clangd::Symbol &Item) {
+ Index.lookup(*Req, [&](const clangd::Symbol &Item) {
auto SerializedItem = ProtobufMarshaller->toProtobuf(Item);
if (!SerializedItem) {
elog("Unable to convert Symbol to protobuf: {0}",
@@ -124,7 +128,7 @@
}
unsigned Sent = 0;
unsigned FailedToSend = 0;
- bool HasMore = Index->fuzzyFind(*Req, [&](const clangd::Symbol &Item) {
+ bool HasMore = Index.fuzzyFind(*Req, [&](const clangd::Symbol &Item) {
auto SerializedItem = ProtobufMarshaller->toProtobuf(Item);
if (!SerializedItem) {
elog("Unable to convert Symbol to protobuf: {0}",
@@ -155,7 +159,7 @@
}
unsigned Sent = 0;
unsigned FailedToSend = 0;
- bool HasMore = Index->refs(*Req, [&](const clangd::Ref &Item) {
+ bool HasMore = Index.refs(*Req, [&](const clangd::Ref &Item) {
auto SerializedItem = ProtobufMarshaller->toProtobuf(Item);
if (!SerializedItem) {
elog("Unable to convert Ref to protobuf: {0}",
@@ -188,7 +192,7 @@
}
unsigned Sent = 0;
unsigned FailedToSend = 0;
- Index->relations(
+ Index.relations(
*Req, [&](const SymbolID &Subject, const clangd::Symbol &Object) {
auto SerializedItem = ProtobufMarshaller->toProtobuf(Subject, Object);
if (!SerializedItem) {
@@ -210,22 +214,57 @@
return grpc::Status::OK;
}
- std::unique_ptr<clangd::SymbolIndex> Index;
std::unique_ptr<Marshaller> ProtobufMarshaller;
+ clangd::SymbolIndex &Index;
};
-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::vfs::Status &LastStatus,
+ llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &FS) {
+ auto Status = FS->status(IndexPath);
+ if (!Status)
+ return;
+ const auto NewModificationTime = Status->getLastModificationTime();
+ // Current index is newer than the one before: no reload is needed.
+ if (NewModificationTime <= LastStatus.getLastModificationTime())
+ return;
+ vlog("Found new index version: existing index was modified at {0}, new "
+ "index was modified at {1}. Attempting to reload.",
+ LastStatus.getLastModificationTime(), NewModificationTime);
+ std::unique_ptr<clang::clangd::SymbolIndex> NewIndex = loadIndex(IndexPath);
+ if (!NewIndex) {
+ vlog("Failed to load new index. Old index will be served.");
+ return;
+ }
+ Index->reset(std::move(NewIndex));
+ log("New index version loaded. Last modification time: {0}.",
+ NewModificationTime);
+ LastStatus = *Status;
+}
+
+void runServer(clangd::SymbolIndex *Index, llvm::StringRef ServerAddress,
+ llvm::StringRef IndexPath) {
+ RemoteIndexServer Service(*Index, 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 ServerShutdownWatcher([&]() {
+ const auto WATCHER_FREQUENCY = std::chrono::seconds(5);
+ while (!clang::clangd::shutdownRequested())
+ std::this_thread::sleep_for(WATCHER_FREQUENCY);
+ Server->Shutdown();
+ });
+
Server->Wait();
+ ServerShutdownWatcher.join();
}
} // namespace
@@ -239,6 +278,7 @@
using namespace clang::clangd::remote;
llvm::cl::ParseCommandLineOptions(argc, argv, Overview);
llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
+ llvm::sys::SetInterruptFunction(&clang::clangd::requestShutdown);
if (!llvm::sys::path::is_absolute(IndexRoot)) {
llvm::errs() << "Index root should be an absolute path.\n";
@@ -273,12 +313,30 @@
if (Tracer)
TracingSession.emplace(*Tracer);
- std::unique_ptr<clang::clangd::SymbolIndex> Index = openIndex(IndexPath);
+ auto Index = std::make_unique<clang::clangd::SwapIndex>(
+ clang::clangd::loadIndex(IndexPath));
if (!Index) {
llvm::errs() << "Failed to open the index.\n";
return -1;
}
- runServer(std::move(Index), ServerAddress);
+ std::thread HotReloadThread([&]() {
+ clang::clangd::RealThreadsafeFS TFS;
+ auto FS = TFS.view(llvm::None);
+ auto Status = FS->status(IndexPath);
+ assert(Status);
+ if (!Status)
+ return;
+ llvm::vfs::Status LastStatus = *Status;
+ const auto REFRESH_FREQUENCY = std::chrono::seconds(90);
+ while (!clang::clangd::shutdownRequested()) {
+ std::this_thread::sleep_for(REFRESH_FREQUENCY);
+ hotReload(Index.get(), llvm::StringRef(IndexPath), LastStatus, FS);
+ }
+ });
+
+ runServer(Index.get(), ServerAddress, IndexPath);
+
+ HotReloadThread.join();
}
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits