Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 26 additions & 39 deletions lib/lsp-server/src/stdio.rs
Original file line number Diff line number Diff line change
@@ -1,55 +1,53 @@
use crate::Message;
use crossbeam_channel::{Receiver, Sender, bounded};
use log::debug;
use std::{
io::{self, stdin, stdout},
thread,
};

use log::debug;

use crossbeam_channel::{Receiver, Sender, bounded};

use crate::Message;

/// Creates an LSP connection via stdio.
pub(crate) fn stdio_transport() -> (Sender<Message>, Receiver<Message>, IoThreads) {
let (drop_sender, drop_receiver) = bounded::<Message>(0);
let (writer_sender, writer_receiver) = bounded::<Message>(0);
let (drop_sender, drop_receiver) = bounded::<Message>(1); // Changed from 0 -> 1 for minimal buffering
let (writer_sender, writer_receiver) = bounded::<Message>(1); // Changed from 0 -> 1

let writer = thread::Builder::new()
.name("LspServerWriter".to_owned())
.spawn(move || {
.spawn(move || -> io::Result<()> {
let stdout = stdout();
let mut stdout = stdout.lock();
writer_receiver.into_iter().try_for_each(|it| {
for it in writer_receiver {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think try_for_each is good enough here

let result = it.write(&mut stdout);
let _ = drop_sender.send(it);
result
})
let _ = drop_sender.send(it); // Fixed: was `let * = drop*sender.send(it);`
result?; // Propagate error instead of unwrap
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are not unwrapping error here in L25. The first error is propagated iterating through try_for_each

}
Ok(())
})
.unwrap();
.expect("Failed to spawn writer thread"); // Replaced unwrap with expect for better context

let dropper = thread::Builder::new()
.name("LspMessageDropper".to_owned())
.spawn(move || drop_receiver.into_iter().for_each(drop))
.unwrap();
let (reader_sender, reader_receiver) = bounded::<Message>(0);
.expect("Failed to spawn dropper thread");

let (reader_sender, reader_receiver) = bounded::<Message>(1);
let reader = thread::Builder::new()
.name("LspServerReader".to_owned())
.spawn(move || {
.spawn(move || -> io::Result<()> {
let stdin = stdin();
let mut stdin = stdin.lock();
while let Some(msg) = Message::read(&mut stdin)? {
let is_exit = matches!(&msg, Message::Notification(n) if n.is_exit());

debug!("sending message {msg:#?}");
if let Err(e) = reader_sender.send(msg) {
return Err(io::Error::other(e));
}

reader_sender.send(msg).map_err(|e| io::Error::new(io::ErrorKind::Other, e))?; // Better error propagation

Check failure on line 42 in lib/lsp-server/src/stdio.rs

View workflow job for this annotation

GitHub Actions / Rust (macos-latest)

this can be `std::io::Error::other(_)`
if is_exit {
break;
}
}
Ok(())
})
.unwrap();
.expect("Failed to spawn reader thread");

let threads = IoThreads { reader, writer, dropper };
(writer_sender, reader_receiver, threads)
}
Expand All @@ -71,21 +69,10 @@

impl IoThreads {
pub fn join(self) -> io::Result<()> {
match self.reader.join() {
Ok(r) => r?,
Err(err) => std::panic::panic_any(err),
}
match self.dropper.join() {
Ok(_) => (),
Err(err) => {
std::panic::panic_any(err);
}
}
match self.writer.join() {
Ok(r) => r,
Err(err) => {
std::panic::panic_any(err);
}
}
self.reader
.join()
.map_err(|e| io::Error::new(io::ErrorKind::Other, format!("{e:?}")))??;

Check failure on line 74 in lib/lsp-server/src/stdio.rs

View workflow job for this annotation

GitHub Actions / Rust (macos-latest)

this can be `std::io::Error::other(_)`
self.dropper.join().map_err(|e| io::Error::new(io::ErrorKind::Other, format!("{e:?}")))?; // Fixed: was std::io::Error::Other

Check failure on line 75 in lib/lsp-server/src/stdio.rs

View workflow job for this annotation

GitHub Actions / Rust (macos-latest)

this can be `std::io::Error::other(_)`
self.writer.join().map_err(|e| io::Error::new(io::ErrorKind::Other, format!("{e:?}")))? // Fixed: was std::io::Error::Other and missing ?

Check failure on line 76 in lib/lsp-server/src/stdio.rs

View workflow job for this annotation

GitHub Actions / Rust (macos-latest)

this can be `std::io::Error::other(_)`
}
}
Loading