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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits