mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-22 11:24:35 +00:00
ruff server
no longer hangs after shutdown (#11222)
## Summary
Fixes https://github.com/astral-sh/ruff/issues/11207.
The server would hang after handling a shutdown request on
`IoThreads::join()` because a global sender (`MESSENGER`, used to send
`window/showMessage` notifications) would remain allocated even after
the event loop finished, which kept the writer I/O thread channel open.
To fix this, I've made a few structural changes to `ruff server`. I've
wrapped the send/receive channels and thread join handle behind a new
struct, `Connection`, which facilitates message sending and receiving,
and also runs `IoThreads::join()` after the event loop finishes. To
control the number of sender channels, the `Connection` wraps the sender
channel in an `Arc` and only allows the creation of a wrapper type,
`ClientSender`, which hold a weak reference to this `Arc` instead of
direct channel access. The wrapper type implements the channel methods
directly to prevent access to the inner channel (which would allow the
channel to be cloned). ClientSender's function is analogous to
[`WeakSender` in
`tokio`](https://docs.rs/tokio/latest/tokio/sync/mpsc/struct.WeakSender.html).
Additionally, the receiver channel cannot be accessed directly - the
`Connection` only exposes an iterator over it.
These changes will guarantee that all channels are closed before the I/O
threads are joined.
## Test Plan
Repeatedly open and close an editor utilizing `ruff server` while
observing the task monitor. The net total amount of open `ruff`
instances should be zero once all editor windows have closed.
The following logs should also appear after the server is shut down:
<img width="835" alt="Screenshot 2024-04-30 at 3 56 22 PM"
src="404b74f5
-ef08-4bb4-9fa2-72e72b946695">
This can be tested on VS Code by changing the settings and then checking
`Output`.
This commit is contained in:
parent
9e69cd6e93
commit
dfbeca5bdd
5 changed files with 189 additions and 53 deletions
|
@ -6,9 +6,9 @@ use crate::server::ClientSender;
|
|||
|
||||
static MESSENGER: OnceLock<ClientSender> = OnceLock::new();
|
||||
|
||||
pub(crate) fn init_messenger(client_sender: &ClientSender) {
|
||||
pub(crate) fn init_messenger(client_sender: ClientSender) {
|
||||
MESSENGER
|
||||
.set(client_sender.clone())
|
||||
.set(client_sender)
|
||||
.expect("messenger should only be initialized once");
|
||||
|
||||
// unregister any previously registered panic hook
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue