mirror of
https://github.com/denoland/deno.git
synced 2024-12-31 11:34:15 -05:00
refactor(lsp): remove performance
from StateSnapshot
(#13403)
This commit is contained in:
parent
3595f37b07
commit
1ab5dea367
4 changed files with 85 additions and 84 deletions
|
@ -5,7 +5,9 @@ use super::client::Client;
|
|||
use super::documents;
|
||||
use super::documents::Documents;
|
||||
use super::language_server;
|
||||
use super::performance::Performance;
|
||||
use super::tsc;
|
||||
use super::tsc::TsServer;
|
||||
|
||||
use crate::diagnostics;
|
||||
|
||||
|
@ -91,13 +93,30 @@ impl DiagnosticCollection {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct DiagnosticsServer {
|
||||
channel: Option<mpsc::UnboundedSender<()>>,
|
||||
collection: Arc<Mutex<DiagnosticCollection>>,
|
||||
client: Client,
|
||||
performance: Arc<Performance>,
|
||||
ts_server: Arc<TsServer>,
|
||||
}
|
||||
|
||||
impl DiagnosticsServer {
|
||||
pub fn new(
|
||||
client: Client,
|
||||
performance: Arc<Performance>,
|
||||
ts_server: Arc<TsServer>,
|
||||
) -> Self {
|
||||
DiagnosticsServer {
|
||||
channel: Default::default(),
|
||||
collection: Default::default(),
|
||||
client,
|
||||
performance,
|
||||
ts_server,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn get(
|
||||
&self,
|
||||
specifier: &ModuleSpecifier,
|
||||
|
@ -127,12 +146,13 @@ impl DiagnosticsServer {
|
|||
pub(crate) fn start(
|
||||
&mut self,
|
||||
language_server: Arc<Mutex<language_server::Inner>>,
|
||||
client: Client,
|
||||
ts_server: Arc<tsc::TsServer>,
|
||||
) {
|
||||
let (tx, mut rx) = mpsc::unbounded_channel::<()>();
|
||||
self.channel = Some(tx);
|
||||
let collection = self.collection.clone();
|
||||
let client = self.client.clone();
|
||||
let performance = self.performance.clone();
|
||||
let ts_server = self.ts_server.clone();
|
||||
|
||||
let _join_handle = thread::spawn(move || {
|
||||
let runtime = create_basic_runtime();
|
||||
|
@ -178,7 +198,8 @@ impl DiagnosticsServer {
|
|||
&client,
|
||||
collection.clone(),
|
||||
snapshot,
|
||||
&ts_server
|
||||
&ts_server,
|
||||
performance.clone(),
|
||||
).await;
|
||||
}
|
||||
}
|
||||
|
@ -609,13 +630,12 @@ async fn update_diagnostics(
|
|||
collection: Arc<Mutex<DiagnosticCollection>>,
|
||||
snapshot: Arc<language_server::StateSnapshot>,
|
||||
ts_server: &tsc::TsServer,
|
||||
performance: Arc<Performance>,
|
||||
) {
|
||||
let mark = snapshot.performance.mark("update_diagnostics", None::<()>);
|
||||
let mark = performance.mark("update_diagnostics", None::<()>);
|
||||
|
||||
let lint = async {
|
||||
let mark = snapshot
|
||||
.performance
|
||||
.mark("update_diagnostics_lint", None::<()>);
|
||||
let mark = performance.mark("update_diagnostics_lint", None::<()>);
|
||||
let collection = collection.clone();
|
||||
let diagnostics = generate_lint_diagnostics(&snapshot, collection.clone())
|
||||
.await
|
||||
|
@ -629,13 +649,11 @@ async fn update_diagnostics(
|
|||
collection.set(DiagnosticSource::DenoLint, diagnostic_record);
|
||||
}
|
||||
publish_diagnostics(client, &mut collection, &snapshot).await;
|
||||
snapshot.performance.measure(mark);
|
||||
performance.measure(mark);
|
||||
};
|
||||
|
||||
let ts = async {
|
||||
let mark = snapshot
|
||||
.performance
|
||||
.mark("update_diagnostics_ts", None::<()>);
|
||||
let mark = performance.mark("update_diagnostics_ts", None::<()>);
|
||||
let collection = collection.clone();
|
||||
let diagnostics =
|
||||
generate_ts_diagnostics(snapshot.clone(), collection.clone(), ts_server)
|
||||
|
@ -649,13 +667,11 @@ async fn update_diagnostics(
|
|||
collection.set(DiagnosticSource::TypeScript, diagnostic_record);
|
||||
}
|
||||
publish_diagnostics(client, &mut collection, &snapshot).await;
|
||||
snapshot.performance.measure(mark);
|
||||
performance.measure(mark);
|
||||
};
|
||||
|
||||
let deps = async {
|
||||
let mark = snapshot
|
||||
.performance
|
||||
.mark("update_diagnostics_deps", None::<()>);
|
||||
let mark = performance.mark("update_diagnostics_deps", None::<()>);
|
||||
let collection = collection.clone();
|
||||
let diagnostics =
|
||||
generate_deps_diagnostics(snapshot.clone(), collection.clone())
|
||||
|
@ -669,11 +685,11 @@ async fn update_diagnostics(
|
|||
collection.set(DiagnosticSource::Deno, diagnostic_record);
|
||||
}
|
||||
publish_diagnostics(client, &mut collection, &snapshot).await;
|
||||
snapshot.performance.measure(mark);
|
||||
performance.measure(mark);
|
||||
};
|
||||
|
||||
tokio::join!(lint, ts, deps);
|
||||
snapshot.performance.measure(mark);
|
||||
performance.measure(mark);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -37,6 +37,7 @@ use super::config::ConfigSnapshot;
|
|||
use super::config::SETTINGS_SECTION;
|
||||
use super::diagnostics;
|
||||
use super::diagnostics::DiagnosticSource;
|
||||
use super::diagnostics::DiagnosticsServer;
|
||||
use super::documents::to_hover_text;
|
||||
use super::documents::to_lsp_range;
|
||||
use super::documents::AssetOrDocument;
|
||||
|
@ -80,7 +81,6 @@ pub(crate) struct StateSnapshot {
|
|||
pub maybe_lint_config: Option<LintConfig>,
|
||||
pub maybe_fmt_config: Option<FmtConfig>,
|
||||
pub module_registries: registries::ModuleRegistry,
|
||||
pub performance: Performance,
|
||||
pub url_map: urls::LspUrlMap,
|
||||
}
|
||||
|
||||
|
@ -118,7 +118,7 @@ pub(crate) struct Inner {
|
|||
/// The URL for the import map which is used to determine relative imports.
|
||||
maybe_import_map_uri: Option<Url>,
|
||||
/// A collection of measurements which instrument that performance of the LSP.
|
||||
performance: Performance,
|
||||
performance: Arc<Performance>,
|
||||
/// A memoized version of fixable diagnostic codes retrieved from TypeScript.
|
||||
ts_fixable_diagnostics: Vec<String>,
|
||||
/// An abstraction that handles interactions with TypeScript.
|
||||
|
@ -143,14 +143,20 @@ impl Inner {
|
|||
registries::ModuleRegistry::new(&module_registries_location);
|
||||
let location = dir.root.join(CACHE_PATH);
|
||||
let documents = Documents::new(&location);
|
||||
let ts_server = Arc::new(TsServer::new());
|
||||
let performance = Arc::new(Performance::default());
|
||||
let ts_server = Arc::new(TsServer::new(performance.clone()));
|
||||
let config = Config::new(client.clone());
|
||||
let diagnostics_server = DiagnosticsServer::new(
|
||||
client.clone(),
|
||||
performance.clone(),
|
||||
ts_server.clone(),
|
||||
);
|
||||
|
||||
Self {
|
||||
assets: Default::default(),
|
||||
client,
|
||||
config,
|
||||
diagnostics_server: Default::default(),
|
||||
diagnostics_server,
|
||||
documents,
|
||||
maybe_cache_path: None,
|
||||
maybe_lint_config: None,
|
||||
|
@ -161,7 +167,7 @@ impl Inner {
|
|||
maybe_import_map_uri: None,
|
||||
module_registries,
|
||||
module_registries_location,
|
||||
performance: Default::default(),
|
||||
performance,
|
||||
ts_fixable_diagnostics: Default::default(),
|
||||
ts_server,
|
||||
url_map: Default::default(),
|
||||
|
@ -370,7 +376,6 @@ impl Inner {
|
|||
maybe_lint_config: self.maybe_lint_config.clone(),
|
||||
maybe_fmt_config: self.maybe_fmt_config.clone(),
|
||||
module_registries: self.module_registries.clone(),
|
||||
performance: self.performance.clone(),
|
||||
url_map: self.url_map.clone(),
|
||||
}))
|
||||
}
|
||||
|
@ -2360,11 +2365,7 @@ impl lspower::LanguageServer for LanguageServer {
|
|||
params: InitializeParams,
|
||||
) -> LspResult<InitializeResult> {
|
||||
let mut language_server = self.0.lock().await;
|
||||
let client = language_server.client.clone();
|
||||
let ts_server = language_server.ts_server.clone();
|
||||
language_server
|
||||
.diagnostics_server
|
||||
.start(self.0.clone(), client, ts_server);
|
||||
language_server.diagnostics_server.start(self.0.clone());
|
||||
language_server.initialize(params).await
|
||||
}
|
||||
|
||||
|
|
|
@ -72,11 +72,11 @@ impl From<PerformanceMark> for PerformanceMeasure {
|
|||
///
|
||||
/// The structure will limit the size of measurements to the most recent 1000,
|
||||
/// and will roll off when that limit is reached.
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug)]
|
||||
pub struct Performance {
|
||||
counts: Arc<Mutex<HashMap<String, u32>>>,
|
||||
counts: Mutex<HashMap<String, u32>>,
|
||||
max_size: usize,
|
||||
measures: Arc<Mutex<VecDeque<PerformanceMeasure>>>,
|
||||
measures: Mutex<VecDeque<PerformanceMeasure>>,
|
||||
}
|
||||
|
||||
impl Default for Performance {
|
||||
|
|
|
@ -4,6 +4,7 @@ use super::code_lens;
|
|||
use super::config;
|
||||
use super::language_server;
|
||||
use super::language_server::StateSnapshot;
|
||||
use super::performance::Performance;
|
||||
use super::refactor::RefactorCodeActionData;
|
||||
use super::refactor::ALL_KNOWN_REFACTOR_ACTION_KINDS;
|
||||
use super::refactor::EXTRACT_CONSTANT;
|
||||
|
@ -89,10 +90,10 @@ type Request = (
|
|||
pub struct TsServer(mpsc::UnboundedSender<Request>);
|
||||
|
||||
impl TsServer {
|
||||
pub fn new() -> Self {
|
||||
pub fn new(performance: Arc<Performance>) -> Self {
|
||||
let (tx, mut rx) = mpsc::unbounded_channel::<Request>();
|
||||
let _join_handle = thread::spawn(move || {
|
||||
let mut ts_runtime = js_runtime();
|
||||
let mut ts_runtime = js_runtime(performance);
|
||||
|
||||
let runtime = create_basic_runtime();
|
||||
runtime.block_on(async {
|
||||
|
@ -2182,6 +2183,7 @@ struct Response {
|
|||
|
||||
struct State<'a> {
|
||||
last_id: usize,
|
||||
performance: Arc<Performance>,
|
||||
response: Option<Response>,
|
||||
state_snapshot: Arc<StateSnapshot>,
|
||||
snapshots: HashMap<(ModuleSpecifier, Cow<'a, str>), String>,
|
||||
|
@ -2189,9 +2191,13 @@ struct State<'a> {
|
|||
}
|
||||
|
||||
impl<'a> State<'a> {
|
||||
fn new(state_snapshot: Arc<StateSnapshot>) -> Self {
|
||||
fn new(
|
||||
state_snapshot: Arc<StateSnapshot>,
|
||||
performance: Arc<Performance>,
|
||||
) -> Self {
|
||||
Self {
|
||||
last_id: 1,
|
||||
performance,
|
||||
response: None,
|
||||
state_snapshot,
|
||||
snapshots: HashMap::default(),
|
||||
|
@ -2285,13 +2291,10 @@ fn op_dispose(
|
|||
state: &mut State,
|
||||
args: SourceSnapshotArgs,
|
||||
) -> Result<bool, AnyError> {
|
||||
let mark = state
|
||||
.state_snapshot
|
||||
.performance
|
||||
.mark("op_dispose", Some(&args));
|
||||
let mark = state.performance.mark("op_dispose", Some(&args));
|
||||
let specifier = state.normalize_specifier(&args.specifier)?;
|
||||
state.snapshots.remove(&(specifier, args.version.into()));
|
||||
state.state_snapshot.performance.measure(mark);
|
||||
state.performance.measure(mark);
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
|
@ -2302,16 +2305,13 @@ struct SpecifierArgs {
|
|||
}
|
||||
|
||||
fn op_exists(state: &mut State, args: SpecifierArgs) -> Result<bool, AnyError> {
|
||||
let mark = state
|
||||
.state_snapshot
|
||||
.performance
|
||||
.mark("op_exists", Some(&args));
|
||||
let mark = state.performance.mark("op_exists", Some(&args));
|
||||
let specifier = state.normalize_specifier(args.specifier)?;
|
||||
let result = state
|
||||
.state_snapshot
|
||||
.documents
|
||||
.contains_specifier(&specifier);
|
||||
state.state_snapshot.performance.measure(mark);
|
||||
state.performance.measure(mark);
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
|
@ -2330,10 +2330,7 @@ fn op_get_change_range(
|
|||
state: &mut State,
|
||||
args: GetChangeRangeArgs,
|
||||
) -> Result<Value, AnyError> {
|
||||
let mark = state
|
||||
.state_snapshot
|
||||
.performance
|
||||
.mark("op_get_change_range", Some(&args));
|
||||
let mark = state.performance.mark("op_get_change_range", Some(&args));
|
||||
let specifier = state.normalize_specifier(&args.specifier)?;
|
||||
cache_snapshot(state, &specifier, args.version.clone())?;
|
||||
let r = if let Some(current) = state
|
||||
|
@ -2369,7 +2366,7 @@ fn op_get_change_range(
|
|||
))
|
||||
};
|
||||
|
||||
state.state_snapshot.performance.measure(mark);
|
||||
state.performance.measure(mark);
|
||||
r
|
||||
}
|
||||
|
||||
|
@ -2377,10 +2374,7 @@ fn op_get_length(
|
|||
state: &mut State,
|
||||
args: SourceSnapshotArgs,
|
||||
) -> Result<usize, AnyError> {
|
||||
let mark = state
|
||||
.state_snapshot
|
||||
.performance
|
||||
.mark("op_get_length", Some(&args));
|
||||
let mark = state.performance.mark("op_get_length", Some(&args));
|
||||
let specifier = state.normalize_specifier(args.specifier)?;
|
||||
let r = if let Some(Some(asset)) = state.state_snapshot.assets.get(&specifier)
|
||||
{
|
||||
|
@ -2393,7 +2387,7 @@ fn op_get_length(
|
|||
.unwrap();
|
||||
Ok(content.encode_utf16().count())
|
||||
};
|
||||
state.state_snapshot.performance.measure(mark);
|
||||
state.performance.measure(mark);
|
||||
r
|
||||
}
|
||||
|
||||
|
@ -2410,10 +2404,7 @@ fn op_get_text(
|
|||
state: &mut State,
|
||||
args: GetTextArgs,
|
||||
) -> Result<String, AnyError> {
|
||||
let mark = state
|
||||
.state_snapshot
|
||||
.performance
|
||||
.mark("op_get_text", Some(&args));
|
||||
let mark = state.performance.mark("op_get_text", Some(&args));
|
||||
let specifier = state.normalize_specifier(args.specifier)?;
|
||||
let content =
|
||||
if let Some(Some(content)) = state.state_snapshot.assets.get(&specifier) {
|
||||
|
@ -2425,7 +2416,7 @@ fn op_get_text(
|
|||
.get(&(specifier, args.version.into()))
|
||||
.unwrap()
|
||||
};
|
||||
state.state_snapshot.performance.measure(mark);
|
||||
state.performance.measure(mark);
|
||||
Ok(text::slice(content, args.start..args.end).to_string())
|
||||
}
|
||||
|
||||
|
@ -2433,13 +2424,10 @@ fn op_load(
|
|||
state: &mut State,
|
||||
args: SpecifierArgs,
|
||||
) -> Result<Option<String>, AnyError> {
|
||||
let mark = state
|
||||
.state_snapshot
|
||||
.performance
|
||||
.mark("op_load", Some(&args));
|
||||
let mark = state.performance.mark("op_load", Some(&args));
|
||||
let specifier = state.normalize_specifier(args.specifier)?;
|
||||
let document = state.state_snapshot.documents.get(&specifier);
|
||||
state.state_snapshot.performance.measure(mark);
|
||||
state.performance.measure(mark);
|
||||
Ok(document.map(|d| d.content().to_string()))
|
||||
}
|
||||
|
||||
|
@ -2447,10 +2435,7 @@ fn op_resolve(
|
|||
state: &mut State,
|
||||
args: ResolveArgs,
|
||||
) -> Result<Vec<Option<(String, String)>>, AnyError> {
|
||||
let mark = state
|
||||
.state_snapshot
|
||||
.performance
|
||||
.mark("op_resolve", Some(&args));
|
||||
let mark = state.performance.mark("op_resolve", Some(&args));
|
||||
let referrer = state.normalize_specifier(&args.base)?;
|
||||
|
||||
let result = if let Some(resolved) = state
|
||||
|
@ -2476,7 +2461,7 @@ fn op_resolve(
|
|||
))
|
||||
};
|
||||
|
||||
state.state_snapshot.performance.measure(mark);
|
||||
state.performance.measure(mark);
|
||||
result
|
||||
}
|
||||
|
||||
|
@ -2510,10 +2495,7 @@ fn op_script_version(
|
|||
state: &mut State,
|
||||
args: ScriptVersionArgs,
|
||||
) -> Result<Option<String>, AnyError> {
|
||||
let mark = state
|
||||
.state_snapshot
|
||||
.performance
|
||||
.mark("op_script_version", Some(&args));
|
||||
let mark = state.performance.mark("op_script_version", Some(&args));
|
||||
let specifier = state.normalize_specifier(args.specifier)?;
|
||||
let r = if specifier.scheme() == "asset" {
|
||||
if state.state_snapshot.assets.contains_key(&specifier) {
|
||||
|
@ -2530,22 +2512,22 @@ fn op_script_version(
|
|||
Ok(script_version)
|
||||
};
|
||||
|
||||
state.state_snapshot.performance.measure(mark);
|
||||
state.performance.measure(mark);
|
||||
r
|
||||
}
|
||||
|
||||
/// Create and setup a JsRuntime based on a snapshot. It is expected that the
|
||||
/// supplied snapshot is an isolate that contains the TypeScript language
|
||||
/// server.
|
||||
fn js_runtime() -> JsRuntime {
|
||||
fn js_runtime(performance: Arc<Performance>) -> JsRuntime {
|
||||
JsRuntime::new(RuntimeOptions {
|
||||
extensions: vec![init_extension()],
|
||||
extensions: vec![init_extension(performance)],
|
||||
startup_snapshot: Some(tsc::compiler_snapshot()),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
fn init_extension() -> Extension {
|
||||
fn init_extension(performance: Arc<Performance>) -> Extension {
|
||||
Extension::builder()
|
||||
.ops(vec![
|
||||
("op_dispose", op_lsp(op_dispose)),
|
||||
|
@ -2559,8 +2541,11 @@ fn init_extension() -> Extension {
|
|||
("op_script_names", op_lsp(op_script_names)),
|
||||
("op_script_version", op_lsp(op_script_version)),
|
||||
])
|
||||
.state(|state| {
|
||||
state.put(State::new(Arc::new(StateSnapshot::default())));
|
||||
.state(move |state| {
|
||||
state.put(State::new(
|
||||
Arc::new(StateSnapshot::default()),
|
||||
performance.clone(),
|
||||
));
|
||||
Ok(())
|
||||
})
|
||||
.build()
|
||||
|
@ -3019,15 +3004,14 @@ pub(crate) fn request(
|
|||
state_snapshot: Arc<StateSnapshot>,
|
||||
method: RequestMethod,
|
||||
) -> Result<Value, AnyError> {
|
||||
let performance = state_snapshot.performance.clone();
|
||||
let request_params = {
|
||||
let (performance, request_params) = {
|
||||
let op_state = runtime.op_state();
|
||||
let mut op_state = op_state.borrow_mut();
|
||||
let state = op_state.borrow_mut::<State>();
|
||||
state.state_snapshot = state_snapshot;
|
||||
state.last_id += 1;
|
||||
let id = state.last_id;
|
||||
method.to_value(state, id)
|
||||
(state.performance.clone(), method.to_value(state, id))
|
||||
};
|
||||
let mark = performance.mark("request", Some(request_params.clone()));
|
||||
let request_src = format!("globalThis.serverRequest({});", request_params);
|
||||
|
@ -3090,7 +3074,7 @@ mod tests {
|
|||
let temp_dir = TempDir::new().expect("could not create temp dir");
|
||||
let location = temp_dir.path().join("deps");
|
||||
let state_snapshot = Arc::new(mock_state_snapshot(sources, &location));
|
||||
let mut runtime = js_runtime();
|
||||
let mut runtime = js_runtime(Default::default());
|
||||
start(&mut runtime, debug, &state_snapshot)
|
||||
.expect("could not start server");
|
||||
let ts_config = TsConfig::new(config);
|
||||
|
|
Loading…
Reference in a new issue