Simplify
This commit is contained in:
parent
dba11cb060
commit
86a4d4cb9c
@ -1,5 +1,5 @@
|
||||
//! A visitor for downcasting arbitrary request (JSON) into a specific type.
|
||||
use std::{panic, time::Instant};
|
||||
use std::panic;
|
||||
|
||||
use serde::{de::DeserializeOwned, Serialize};
|
||||
|
||||
@ -13,7 +13,6 @@ use crate::{
|
||||
pub(crate) struct RequestDispatcher<'a> {
|
||||
pub(crate) req: Option<lsp_server::Request>,
|
||||
pub(crate) global_state: &'a mut GlobalState,
|
||||
pub(crate) request_received: Instant,
|
||||
}
|
||||
|
||||
impl<'a> RequestDispatcher<'a> {
|
||||
@ -34,12 +33,12 @@ impl<'a> RequestDispatcher<'a> {
|
||||
}
|
||||
};
|
||||
let world = panic::AssertUnwindSafe(&mut *self.global_state);
|
||||
let task = panic::catch_unwind(move || {
|
||||
let response = panic::catch_unwind(move || {
|
||||
let result = f(world.0, params);
|
||||
result_to_task::<R>(id, result)
|
||||
result_to_response::<R>(id, result)
|
||||
})
|
||||
.map_err(|_| format!("sync task {:?} panicked", R::METHOD))?;
|
||||
self.global_state.on_task(task);
|
||||
self.global_state.respond(response);
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
@ -64,7 +63,7 @@ impl<'a> RequestDispatcher<'a> {
|
||||
let world = self.global_state.snapshot();
|
||||
move || {
|
||||
let result = f(world, params);
|
||||
result_to_task::<R>(id, result)
|
||||
Task::Response(result_to_response::<R>(id, result))
|
||||
}
|
||||
});
|
||||
|
||||
@ -72,17 +71,14 @@ impl<'a> RequestDispatcher<'a> {
|
||||
}
|
||||
|
||||
pub(crate) fn finish(&mut self) {
|
||||
match self.req.take() {
|
||||
None => (),
|
||||
Some(req) => {
|
||||
log::error!("unknown request: {:?}", req);
|
||||
let resp = lsp_server::Response::new_err(
|
||||
req.id,
|
||||
lsp_server::ErrorCode::MethodNotFound as i32,
|
||||
"unknown request".to_string(),
|
||||
);
|
||||
self.global_state.send(resp.into());
|
||||
}
|
||||
if let Some(req) = self.req.take() {
|
||||
log::error!("unknown request: {:?}", req);
|
||||
let response = lsp_server::Response::new_err(
|
||||
req.id,
|
||||
lsp_server::ErrorCode::MethodNotFound as i32,
|
||||
"unknown request".to_string(),
|
||||
);
|
||||
self.global_state.respond(response)
|
||||
}
|
||||
}
|
||||
|
||||
@ -99,21 +95,20 @@ impl<'a> RequestDispatcher<'a> {
|
||||
return None;
|
||||
}
|
||||
};
|
||||
self.global_state
|
||||
.req_queue
|
||||
.incoming
|
||||
.register(id.clone(), (R::METHOD, self.request_received));
|
||||
Some((id, params))
|
||||
}
|
||||
}
|
||||
|
||||
fn result_to_task<R>(id: lsp_server::RequestId, result: Result<R::Result>) -> Task
|
||||
fn result_to_response<R>(
|
||||
id: lsp_server::RequestId,
|
||||
result: Result<R::Result>,
|
||||
) -> lsp_server::Response
|
||||
where
|
||||
R: lsp_types::request::Request + 'static,
|
||||
R::Params: DeserializeOwned + 'static,
|
||||
R::Result: Serialize + 'static,
|
||||
{
|
||||
let response = match result {
|
||||
match result {
|
||||
Ok(resp) => lsp_server::Response::new_ok(id, &resp),
|
||||
Err(e) => match e.downcast::<LspError>() {
|
||||
Ok(lsp_error) => lsp_server::Response::new_err(id, lsp_error.code, lsp_error.message),
|
||||
@ -133,8 +128,7 @@ where
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
Task::Respond(response)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct NotificationDispatcher<'a> {
|
||||
|
@ -253,13 +253,19 @@ impl GlobalState {
|
||||
self.analysis_host.collect_garbage()
|
||||
}
|
||||
|
||||
pub(crate) fn complete_request(&mut self, request: RequestMetrics) {
|
||||
self.latest_requests.write().record(request)
|
||||
}
|
||||
|
||||
pub(crate) fn send(&mut self, message: lsp_server::Message) {
|
||||
self.sender.send(message).unwrap()
|
||||
}
|
||||
pub(crate) fn respond(&mut self, response: lsp_server::Response) {
|
||||
if let Some((method, start)) = self.req_queue.incoming.complete(response.id.clone()) {
|
||||
let duration = start.elapsed();
|
||||
log::info!("handled req#{} in {:?}", response.id, duration);
|
||||
let metrics =
|
||||
RequestMetrics { id: response.id.clone(), method: method.to_string(), duration };
|
||||
self.latest_requests.write().record(metrics);
|
||||
self.send(response.into());
|
||||
}
|
||||
}
|
||||
pub(crate) fn show_message(&mut self, typ: lsp_types::MessageType, message: String) {
|
||||
show_message(typ, message, &self.sender)
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ use crate::{
|
||||
lsp_utils::{
|
||||
apply_document_changes, is_canceled, notification_is, notification_new, show_message,
|
||||
},
|
||||
request_metrics::RequestMetrics,
|
||||
Result,
|
||||
};
|
||||
|
||||
@ -147,7 +146,7 @@ impl fmt::Debug for Event {
|
||||
return debug_verbose_not(not, f);
|
||||
}
|
||||
}
|
||||
Event::Task(Task::Respond(resp)) => {
|
||||
Event::Task(Task::Response(resp)) => {
|
||||
return f
|
||||
.debug_struct("Response")
|
||||
.field("id", &resp.id)
|
||||
@ -218,7 +217,13 @@ impl GlobalState {
|
||||
}
|
||||
},
|
||||
Event::Task(task) => {
|
||||
self.on_task(task);
|
||||
match task {
|
||||
Task::Response(response) => self.respond(response),
|
||||
Task::Diagnostics(tasks) => {
|
||||
tasks.into_iter().for_each(|task| on_diagnostic_task(task, self))
|
||||
}
|
||||
Task::Unit => (),
|
||||
}
|
||||
self.maybe_collect_garbage();
|
||||
}
|
||||
Event::Vfs(task) => match task {
|
||||
@ -331,7 +336,9 @@ impl GlobalState {
|
||||
}
|
||||
|
||||
fn on_request(&mut self, request_received: Instant, req: Request) -> Result<()> {
|
||||
RequestDispatcher { req: Some(req), global_state: self, request_received }
|
||||
self.req_queue.incoming.register(req.id.clone(), (req.method.clone(), request_received));
|
||||
|
||||
RequestDispatcher { req: Some(req), global_state: self }
|
||||
.on_sync::<lsp_ext::CollectGarbage>(|s, ()| Ok(s.collect_garbage()))?
|
||||
.on_sync::<lsp_ext::JoinLines>(|s, p| handlers::handle_join_lines(s.snapshot(), p))?
|
||||
.on_sync::<lsp_ext::OnEnter>(|s, p| handlers::handle_on_enter(s.snapshot(), p))?
|
||||
@ -492,27 +499,6 @@ impl GlobalState {
|
||||
.finish();
|
||||
Ok(())
|
||||
}
|
||||
pub(crate) fn on_task(&mut self, task: Task) {
|
||||
match task {
|
||||
Task::Respond(response) => {
|
||||
if let Some((method, start)) = self.req_queue.incoming.complete(response.id.clone())
|
||||
{
|
||||
let duration = start.elapsed();
|
||||
log::info!("handled req#{} in {:?}", response.id, duration);
|
||||
self.complete_request(RequestMetrics {
|
||||
id: response.id.clone(),
|
||||
method: method.to_string(),
|
||||
duration,
|
||||
});
|
||||
self.send(response.into());
|
||||
}
|
||||
}
|
||||
Task::Diagnostics(tasks) => {
|
||||
tasks.into_iter().for_each(|task| on_diagnostic_task(task, self))
|
||||
}
|
||||
Task::Unit => (),
|
||||
}
|
||||
}
|
||||
fn update_file_notifications_on_threadpool(&mut self, subscriptions: Vec<FileId>) {
|
||||
log::trace!("updating notifications for {:?}", subscriptions);
|
||||
if self.config.publish_diagnostics {
|
||||
@ -548,13 +534,13 @@ impl GlobalState {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum Task {
|
||||
Respond(Response),
|
||||
Diagnostics(Vec<DiagnosticTask>),
|
||||
Response(Response),
|
||||
Diagnostics(()),
|
||||
Unit,
|
||||
}
|
||||
|
||||
pub(crate) type ReqHandler = fn(&mut GlobalState, Response);
|
||||
pub(crate) type ReqQueue = lsp_server::ReqQueue<(&'static str, Instant), ReqHandler>;
|
||||
pub(crate) type ReqQueue = lsp_server::ReqQueue<(String, Instant), ReqHandler>;
|
||||
const DO_NOTHING: ReqHandler = |_, _| ();
|
||||
|
||||
fn on_diagnostic_task(task: DiagnosticTask, global_state: &mut GlobalState) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user