https://bugs.kde.org/show_bug.cgi?id=438790
--- Comment #1 from nyanpasu64 <nyanpas...@tuta.io> --- I investigated the LSP client. Pressing Ctrl+C in gdb during the hang pointed within LSPClientServerManagerImpl::~LSPClientServerManagerImpl(). The corresponding function as of today's master is https://github.com/KDE/kate/blob/45362eaa64ede7b0dbb172a5c154859c76fd6231/addons/lspclient/lspclientservermanager.cpp#L213, which matches my local 21.04.2 function. According to the source, Kate's LSP client is designed to sleep the UI thread for 500ms (using QThread::msleep(500)) after sending a termination request to LSPs, before sending SIGTERM and SIGKILL (each with a 100ms delay afterwards). I'm not sure if waiting for language servers to terminate is a bad design, or if blocking the UI thread is a bad design, or what would be better. However, the current design is implemented poorly, since it sleeps for 700ms even though `m_servers` is empty (for example, in an empty Kate window without open files)! Also there's some oddities going on, with `connect(s.data(), &LSPClientServer::stateChanged, this, handler)`, a `QTimer t` that never fires, and a `QEventLoop q` that seems to go unused aside from calling quit() on it. I don't understand what `count` is doing either. Maybe it can be removed entirely (but I don't know what to do with `handler`). I think it's dead code that used to be active: https://github.com/KDE/kate/commit/724a9d0af0e9b4ec04d91f74ca9bbc9dbeaa2ee2 Additionally, the current code checks for `auto &s = si.server; if (!s)` to determine whether to request shutdown, SIGTERM, then SIGKILL. I don't think `ServerInfo { QSharedPointer<LSPClientServer> server` will become a null pointer when the LSPClientServer shuts down (but I didn't verify it doesn't get overwritten). Assuming it doesn't become a null pointer, that means Kate calls LSPClientServer::stop() (which calls QProcess::terminate()/kill()) even if the process is already dead! ---- An easy partial fix is to skip the m_servers/msleep() song and dance entirely if m_servers is empty. This will fix the shutdown lag if no language servers are running. If maintainers want to keep the current overall behavior (blocking the UI thread while sending terminate+SIGTERM+SIGKILL), I think a better fix is: - If any servers are active, send a termination request, "join" on them with a 500ms timeout, then remove the servers which have shutdown. - If any servers are left, send SIGTERM, "join" on them with a 100ms timeout, then remove the servers which have shutdown. - If any servers are left, send SIGKILL and don't bother joining anymore. If they don't shutdown from SIGKILL, there's nothing we can do (I think). If you feel like it, you can send the user a popup if LSPs don't respond to termination, SIGTERM, or SIGKILL. Issue is, I don't know how to properly implement "joining", and haven't researched how to do it yet. I can look into it if the maintainers like my proposed control flow. ---- While researching this problem, I was exploring the various Kate plugin APIs, and have some comments about the design. `LSPClientServer::stop(int to_term_ms, int to_kill_ms)` is unintuitive to me, but I don't think it can be significantly improved (aside from using a constant like DONT_TERMINATE instead of -1), since all combinations of {-1, >=0} for the two parameters are used (in ~LSPClientServerPrivate() and ~LSPClientServerManagerImpl(). I also found `LSPClientServerManagerImpl::restart(const ServerList &servers)` (https://github.com/KDE/kate/blob/45362eaa64ede7b0dbb172a5c154859c76fd6231/addons/lspclient/lspclientservermanager.cpp#L392). Instead of waiting for the old process to terminate, it sends a termination request immediately, SIGTERM in 0.4 seconds, SIGKILL in 0.8 seconds, and emits serverChanged() (which somehow respawns the server) in 1.2 seconds. This design is slower and arguably less elegant than waiting for the processes to terminate, but simpler and has more predictable behavior. You can watch the LSP servers stop and start by running `watch -n0.1 'pstree -a $(pgrep kate)'` and triggering LSP restarts in Kate. - Interestingly, if you restart the LSP, then press "jump to definition" before clangd starts up, it fails, but instantly spawns a clangd so pressing "jump to definition" a second time works. - By mapping a shortcut to "Restart All LSP Servers" and holding the shortcut down, you can get Kate to start close to 10 clangd processes at once. I don't know if this is a problem, or how to fix it. -- You are receiving this mail because: You are watching all bug changes.