mirror of https://github.com/helix-editor/helix
Reuse content buffer in JSONRPC recv for LSP and DAP
Previously `recv` for new messages from the language server or debug adapter allocated a fresh Vec for each message. Instead we can reuse the buffer. This resolves TODO comments. Co-authored-by: Rolo <roloedits@gmail.com>pull/13648/head
parent
f6878f62f7
commit
8d2870b94a
|
@ -85,10 +85,11 @@ impl Transport {
|
||||||
async fn recv_server_message(
|
async fn recv_server_message(
|
||||||
reader: &mut Box<dyn AsyncBufRead + Unpin + Send>,
|
reader: &mut Box<dyn AsyncBufRead + Unpin + Send>,
|
||||||
buffer: &mut String,
|
buffer: &mut String,
|
||||||
|
content: &mut Vec<u8>,
|
||||||
) -> Result<Payload> {
|
) -> Result<Payload> {
|
||||||
let mut content_length = None;
|
let mut content_length = None;
|
||||||
loop {
|
loop {
|
||||||
buffer.truncate(0);
|
buffer.clear();
|
||||||
if reader.read_line(buffer).await? == 0 {
|
if reader.read_line(buffer).await? == 0 {
|
||||||
return Err(Error::StreamClosed);
|
return Err(Error::StreamClosed);
|
||||||
};
|
};
|
||||||
|
@ -117,17 +118,17 @@ impl Transport {
|
||||||
}
|
}
|
||||||
|
|
||||||
let content_length = content_length.context("missing content length")?;
|
let content_length = content_length.context("missing content length")?;
|
||||||
|
content.resize(content_length, 0);
|
||||||
//TODO: reuse vector
|
reader.read_exact(content).await?;
|
||||||
let mut content = vec![0; content_length];
|
let msg = std::str::from_utf8(content).context("invalid utf8 from server")?;
|
||||||
reader.read_exact(&mut content).await?;
|
|
||||||
let msg = std::str::from_utf8(&content).context("invalid utf8 from server")?;
|
|
||||||
|
|
||||||
info!("<- DAP {}", msg);
|
info!("<- DAP {}", msg);
|
||||||
|
|
||||||
// try parsing as output (server response) or call (server request)
|
// try parsing as output (server response) or call (server request)
|
||||||
let output: serde_json::Result<Payload> = serde_json::from_str(msg);
|
let output: serde_json::Result<Payload> = serde_json::from_str(msg);
|
||||||
|
|
||||||
|
content.clear();
|
||||||
|
|
||||||
Ok(output?)
|
Ok(output?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,8 +243,15 @@ impl Transport {
|
||||||
client_tx: UnboundedSender<Payload>,
|
client_tx: UnboundedSender<Payload>,
|
||||||
) {
|
) {
|
||||||
let mut recv_buffer = String::new();
|
let mut recv_buffer = String::new();
|
||||||
|
let mut content_buffer = Vec::new();
|
||||||
loop {
|
loop {
|
||||||
match Self::recv_server_message(&mut server_stdout, &mut recv_buffer).await {
|
match Self::recv_server_message(
|
||||||
|
&mut server_stdout,
|
||||||
|
&mut recv_buffer,
|
||||||
|
&mut content_buffer,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
Ok(msg) => match transport.process_server_message(&client_tx, msg).await {
|
Ok(msg) => match transport.process_server_message(&client_tx, msg).await {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
|
|
@ -90,11 +90,12 @@ impl Transport {
|
||||||
async fn recv_server_message(
|
async fn recv_server_message(
|
||||||
reader: &mut (impl AsyncBufRead + Unpin + Send),
|
reader: &mut (impl AsyncBufRead + Unpin + Send),
|
||||||
buffer: &mut String,
|
buffer: &mut String,
|
||||||
|
content: &mut Vec<u8>,
|
||||||
language_server_name: &str,
|
language_server_name: &str,
|
||||||
) -> Result<ServerMessage> {
|
) -> Result<ServerMessage> {
|
||||||
let mut content_length = None;
|
let mut content_length = None;
|
||||||
loop {
|
loop {
|
||||||
buffer.truncate(0);
|
buffer.clear();
|
||||||
if reader.read_line(buffer).await? == 0 {
|
if reader.read_line(buffer).await? == 0 {
|
||||||
return Err(Error::StreamClosed);
|
return Err(Error::StreamClosed);
|
||||||
};
|
};
|
||||||
|
@ -126,11 +127,9 @@ impl Transport {
|
||||||
}
|
}
|
||||||
|
|
||||||
let content_length = content_length.context("missing content length")?;
|
let content_length = content_length.context("missing content length")?;
|
||||||
|
content.resize(content_length, 0);
|
||||||
//TODO: reuse vector
|
reader.read_exact(content).await?;
|
||||||
let mut content = vec![0; content_length];
|
let msg = std::str::from_utf8(content).context("invalid utf8 from server")?;
|
||||||
reader.read_exact(&mut content).await?;
|
|
||||||
let msg = std::str::from_utf8(&content).context("invalid utf8 from server")?;
|
|
||||||
|
|
||||||
info!("{language_server_name} <- {msg}");
|
info!("{language_server_name} <- {msg}");
|
||||||
|
|
||||||
|
@ -255,9 +254,15 @@ impl Transport {
|
||||||
client_tx: UnboundedSender<(LanguageServerId, jsonrpc::Call)>,
|
client_tx: UnboundedSender<(LanguageServerId, jsonrpc::Call)>,
|
||||||
) {
|
) {
|
||||||
let mut recv_buffer = String::new();
|
let mut recv_buffer = String::new();
|
||||||
|
let mut content_buffer = Vec::new();
|
||||||
loop {
|
loop {
|
||||||
match Self::recv_server_message(&mut server_stdout, &mut recv_buffer, &transport.name)
|
match Self::recv_server_message(
|
||||||
.await
|
&mut server_stdout,
|
||||||
|
&mut recv_buffer,
|
||||||
|
&mut content_buffer,
|
||||||
|
&transport.name,
|
||||||
|
)
|
||||||
|
.await
|
||||||
{
|
{
|
||||||
Ok(msg) => {
|
Ok(msg) => {
|
||||||
match transport
|
match transport
|
||||||
|
|
Loading…
Reference in New Issue