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.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
clang-tools-extra/clangd/index/remote/server/Server.cpp | ||
---|---|---|
75–76 | why do we have this extra indirection? | |
87 | why not make this private? also keep using SymbolIndex. also you can make this a reference now. | |
224 | why is this taking a double pointer? I think you can just use a reference here for Index (i.e. clangd::SwapIndex & | |
226 | i think we should rather store the file_status from the original file in here. as we want to reload whenever files size/modification_time has changed. Also it would be nice to use a VFS in here, that way we can move this logic into a helper in the future if other components need similar logic. | |
227 | how's this loop terminated? I would suggest factoring the loop body into a helper and then having a lambda for periodically running it, while looking for an exit signal. | |
259 | i think hotReload thread creation should also be part of the main. | |
268 | you either need to join a thread before its destruction or detach it from the main thread. | |
316–325 | nit: auto Index = std::make_unique<clang::clangd::SwapIndex>(openIndex...); |
clang-tools-extra/clangd/index/remote/server/Server.cpp | ||
---|---|---|
226 | Can you elaborate more on VFS usage? I'm not sure how this would improve existing and potential future code over plain llvm::sys::* calls. |
clang-tools-extra/clangd/index/remote/server/Server.cpp | ||
---|---|---|
226 | it is mostly for unit testing the helper when there's a wider usage. also some users of clangd($Employer's internal editor) doesn't really have a real fs, they surface it through a VFS. it also makes the code a little bit more easier to read, but definitely doesn't require immediate action, so up to you. |
Thanks! Mostly looks good, just couple of nits.
clang-tools-extra/clangd/index/remote/server/Server.cpp | ||
---|---|---|
224 | Again Index is a non-nullptr, so let's use a ref instead. | |
232 | from previous comment: i think we should rather store the file_status from the original file in here. as we want to reload whenever files size/modification_time has changed. it doesn't have to be moving forward let alone share the same timezone restrictions and such provided by system_clock::now. | |
248 | nit: maybe rename to runServerAndWait | |
336 | instead of both asserting and bailing out, maybe just elog before bail-out? + I think what you rather want is grab the inital status outside this lambda. i.e: clang::clangd::RealThreadsafeFS TFS; auto FS = TFS...; auto Status = ....; if(!Status) { // elog and exit, file does not exist } auto Index = ...; if(!Index) { // elog and exit, failed to load index } std::thread ..([FS = TFS.view(), LastStatus = *Status, &Index]{ ... }); runServer(); joinThread(); | |
340 | nit: static constexpr auto RefreshFrequency, i.e. use constexpr and we don't have a different naming convention for constants. same for WatcherFrequency. |
oops, looks like i forgot to hit submit in the morning..
clang-tools-extra/clangd/index/remote/server/Server.cpp | ||
---|---|---|
228 | i beleive equivalent checks for inode number equivalence (at least on linux, using realfilesystem). That's not guranteed to change when you overwrite/modify a file. Sorry if it felt like i meant this, but I was literally suggesting to use != instead of <= when comparing modifcation time, and also incorporating size into the check. Also please let me know if there's something i am missing with the equivalent. It would be also nice to have some tests, as we are starting to add non-trivial functionality to server but not blocking for this patch. (i suppose it would've catched the equivalent problem) | |
234 | i think we should update LastStatus here, as we are going to fail loading the index unless the file changes. so there's no need to retry loading the index if the file hasn't changed. | |
236 | i believe, this should be an elog. | |
240 | nit: maybe also print the size. | |
320 | nit: drop File | |
337 | nit: i would first call hotReload and then sleep to get rid of one extra reload of the index when we are shutting down. | |
344 | nit: return 0; ? |
Address another round of comments.
clang-tools-extra/clangd/index/remote/server/Server.cpp | ||
---|---|---|
234 | Sorry, the comment is off, it belongs to the if statement above. Here, the index file is already different and there is an attempt to reload it. If it succeeds, new index replaces the old one and LastStatus is updated. | |
344 | No need for that in C++. https://en.cppreference.com/w/cpp/language/main_function
|
clang-tools-extra/clangd/index/remote/server/Server.cpp | ||
---|---|---|
234 | right and what I am saying is, even if we fail to load the the index we should still update the LastStatus to prevent redundant retries for a broken index file. e.g:
We could prevent that redundant loads (and failure logs) by caching the LastStatus as soon as the file exists. Does that make sense now? | |
344 | right, hence the nit |
Save last status to prevent redundant updates.
clang-tools-extra/clangd/index/remote/server/Server.cpp | ||
---|---|---|
234 | Ahh, I see now, makes sense. Thanks for the explanation! | |
344 | Hm, why do you think it is better then? I'm not sure if adding no-op lines of code will increase readability/clarity. I'm curious now, is there any reason you prefer explicit return 0;? |
Thanks, LGTM!
clang-tools-extra/clangd/index/remote/server/Server.cpp | ||
---|---|---|
344 | I suppose, mostly aesthetics and being used to it. |
why do we have this extra indirection?