feat: delete useless async snapshot (#1206)

This commit is contained in:
Myriad-Dreamin 2025-01-21 08:52:45 +08:00 committed by GitHub
parent 0a91f0d2b4
commit 4bebc00df2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 43 additions and 106 deletions

View file

@ -352,8 +352,6 @@ impl ServerState {
let snap = self.snapshot().map_err(z_internal_error)?;
just_future(async move {
let snap = snap.receive().await.map_err(z_internal_error)?;
// Parse the package specification. If the user didn't specify the version,
// we try to figure it out automatically by downloading the package index
// or searching the disk.
@ -397,8 +395,6 @@ impl ServerState {
let snap = self.snapshot().map_err(z_internal_error)?;
just_future(async move {
let snap = snap.receive().await.map_err(z_internal_error)?;
// Parse the package specification. If the user didn't specify the version,
// we try to figure it out automatically by downloading the package index
// or searching the disk.
@ -466,7 +462,6 @@ impl ServerState {
let user_action = self.user_action;
just_future(async move {
let snap = snap.receive().await.map_err(z_internal_error)?;
let display_entry = || format!("{entry:?}");
// todo: rootless file
@ -555,7 +550,6 @@ impl ServerState {
pub fn resource_package_dirs(&mut self, _arguments: Vec<JsonValue>) -> AnySchedulableResponse {
let snap = self.snapshot().map_err(z_internal_error)?;
just_future(async move {
let snap = snap.receive().await.map_err(z_internal_error)?;
let paths = snap.world.registry.paths();
let paths = paths.iter().map(|p| p.as_ref()).collect::<Vec<_>>();
serde_json::to_value(paths).map_err(|e| internal_error(e.to_string()))
@ -569,7 +563,6 @@ impl ServerState {
) -> AnySchedulableResponse {
let snap = self.snapshot().map_err(z_internal_error)?;
just_future(async move {
let snap = snap.receive().await.map_err(z_internal_error)?;
let paths = snap.world.registry.local_path();
let paths = paths.as_deref().into_iter().collect::<Vec<_>>();
serde_json::to_value(paths).map_err(|e| internal_error(e.to_string()))
@ -585,7 +578,6 @@ impl ServerState {
let snap = self.snapshot().map_err(z_internal_error)?;
just_future(async move {
let snap = snap.receive().await.map_err(z_internal_error)?;
let packages =
tinymist_query::package::list_package_by_namespace(&snap.world.registry, ns)
.into_iter()
@ -601,12 +593,10 @@ impl ServerState {
&mut self,
mut arguments: Vec<JsonValue>,
) -> AnySchedulableResponse {
let fut = self.query_snapshot().map_err(internal_error)?;
let snap = self.query_snapshot().map_err(internal_error)?;
let info = get_arg!(arguments[1] as PackageInfo);
just_future(async move {
let snap = fut.receive().await.map_err(z_internal_error)?;
let symbols = snap
.run_analysis(|a| {
tinymist_query::docs::package_module_docs(a, &info)
@ -661,10 +651,9 @@ impl ServerState {
info: PackageInfo,
f: impl FnOnce(&mut LocalContextGuard) -> LspResult<T> + Send + Sync,
) -> LspResult<impl Future<Output = LspResult<T>>> {
let fut = self.query_snapshot().map_err(internal_error)?;
let snap = self.query_snapshot().map_err(internal_error)?;
Ok(async move {
let snap = fut.receive().await.map_err(z_internal_error)?;
let world = &snap.world;
let entry: StrResult<EntryState> = Ok(()).and_then(|_| {

View file

@ -257,8 +257,6 @@ pub fn trace_lsp_main(args: TraceLspArgs) -> Result<()> {
let snap = state.snapshot().unwrap();
RUNTIMES.tokio_runtime.block_on(async {
let snap = snap.receive().await.unwrap();
let w = snap.world.task(TaskInputs {
entry: Some(entry),
inputs: Some(inputs),
@ -305,13 +303,13 @@ pub fn query_main(cmds: QueryCommands) -> Result<()> {
let snap = state.snapshot().unwrap();
let res = RUNTIMES.tokio_runtime.block_on(async move {
let w = snap.receive().await.map_err(internal_error)?;
match cmds {
QueryCommands::PackageDocs(args) => {
let pkg = PackageSpec::from_str(&args.id).unwrap();
let path = args.path.map(PathBuf::from);
let path = path
.unwrap_or_else(|| w.world.registry.resolve(&pkg).unwrap().as_ref().into());
let path = path.unwrap_or_else(|| {
snap.world.registry.resolve(&pkg).unwrap().as_ref().into()
});
let res = state
.resource_package_docs_(PackageInfo {
@ -328,8 +326,9 @@ pub fn query_main(cmds: QueryCommands) -> Result<()> {
QueryCommands::CheckPackage(args) => {
let pkg = PackageSpec::from_str(&args.id).unwrap();
let path = args.path.map(PathBuf::from);
let path = path
.unwrap_or_else(|| w.world.registry.resolve(&pkg).unwrap().as_ref().into());
let path = path.unwrap_or_else(|| {
snap.world.registry.resolve(&pkg).unwrap().as_ref().into()
});
state
.check_package(PackageInfo {

View file

@ -1,11 +1,11 @@
use std::sync::Arc;
use serde::{Deserialize, Serialize};
use tinymist_project::LspCompileSnapshot;
use tinymist_std::debug_loc::DataSource;
use typst::text::{FontStretch, FontStyle, FontWeight};
use super::prelude::*;
use crate::project::WorldSnapFut;
use crate::world::font::FontResolver;
#[derive(Debug, Clone, Serialize, Deserialize)]
@ -43,8 +43,7 @@ struct FontResourceResult {
impl ServerState {
/// Get the all valid fonts
pub async fn get_font_resources(snap: WorldSnapFut) -> LspResult<JsonValue> {
let snap = snap.receive().await.map_err(internal_error)?;
pub async fn get_font_resources(snap: LspCompileSnapshot) -> LspResult<JsonValue> {
// fonts
let resolver = &snap.world.font_resolver;
let font_book = resolver.font_book();

View file

@ -3,10 +3,11 @@ use std::{collections::BTreeMap, path::Path, sync::Arc};
// use reflexo_typst::font::GlyphId;
use reflexo_typst::{vector::font::GlyphId, TypstDocument, TypstFont};
use sync_lsp::LspResult;
use tinymist_project::LspCompileSnapshot;
use typst::{syntax::VirtualPath, World};
use crate::world::{base::ShadowApi, EntryState, TaskInputs};
use crate::{project::WorldSnapFut, z_internal_error};
use crate::z_internal_error;
use super::prelude::*;
@ -947,9 +948,7 @@ static CAT_MAP: Lazy<HashMap<&str, SymCategory>> = Lazy::new(|| {
impl ServerState {
/// Get the all valid symbols
pub async fn get_symbol_resources(snap: WorldSnapFut) -> LspResult<JsonValue> {
let snap = snap.receive().await.map_err(z_internal_error)?;
pub async fn get_symbol_resources(snap: LspCompileSnapshot) -> LspResult<JsonValue> {
let mut symbols = ResourceSymbolMap::new();
use typst::symbols::{emoji, sym};
populate_scope(sym().scope(), "sym", SymCategory::Misc, &mut symbols);

View file

@ -9,7 +9,7 @@ use once_cell::sync::OnceCell;
use reflexo_typst::Bytes;
use serde_json::{Map, Value as JsonValue};
use sync_lsp::*;
use tinymist_project::ProjectResolutionKind;
use tinymist_project::{Interrupt, ProjectResolutionKind};
use tinymist_query::{to_typst_range, PositionEncoding};
use tinymist_std::error::prelude::*;
use tinymist_std::ImmutPath;
@ -165,10 +165,12 @@ impl ServerState {
info!("the entry file of TypstActor(primary) is changing to {next_entry:?}");
self.project.change_task(TaskInputs {
let id = self.project.state.primary.id.clone();
let task = TaskInputs {
entry: Some(next_entry.clone()),
..Default::default()
});
};
self.project.interrupt(Interrupt::ChangeTask(id, task));
Ok(true)
}
@ -287,8 +289,8 @@ impl ServerState {
}
fn update_source(&mut self, files: FileChangeSet) -> Result<()> {
self.project
.add_memory_changes(MemoryEvent::Update(files.clone()));
let intr = Interrupt::Memory(MemoryEvent::Update(files.clone()));
self.project.interrupt(intr);
Ok(())
}

View file

@ -12,7 +12,7 @@
//!
//! We use typst by creating a [`ProjectCompiler`] and
//! running compiler with callbacking [`CompileHandlerImpl`] incrementally. An
//! additional [`LocalCompileHandler`] is also created to control the
//! additional [`ProjectState`] is also created to control the
//! [`ProjectCompiler`].
//!
//! The [`CompileHandlerImpl`] will push information to other actors.
@ -34,12 +34,11 @@ use tinymist_query::{
VersionedDocument,
};
use tinymist_std::{bail, error::prelude::*};
use tokio::sync::{mpsc, oneshot};
use tokio::sync::mpsc;
use typst::diag::SourceDiagnostic;
use crate::actor::editor::{CompileStatus, DocVersion, EditorRequest, TinymistCompileStatusEnum};
use crate::stats::{CompilerQueryStats, QueryStatGuard};
use crate::world::vfs::MemoryEvent;
type EditorSender = mpsc::UnboundedSender<EditorRequest>;
@ -99,31 +98,23 @@ pub struct ProjectState {
impl ProjectState {
/// Snapshot the compiler thread for tasks
pub fn snapshot(&mut self) -> Result<WorldSnapFut> {
let (tx, rx) = oneshot::channel();
let snap = self.state.snapshot();
let _ = tx.send(snap);
Ok(WorldSnapFut { rx })
pub fn snapshot(&mut self) -> Result<LspCompileSnapshot> {
Ok(self.state.snapshot())
}
/// Snapshot the compiler thread for language queries
pub fn query_snapshot(&mut self, q: Option<&CompilerQueryRequest>) -> Result<QuerySnapFut> {
let fut = self.snapshot()?;
pub fn query_snapshot(&mut self, q: Option<&CompilerQueryRequest>) -> Result<LspQuerySnapshot> {
let snap = self.snapshot()?;
let analysis = self.analysis.clone();
let rev_lock = analysis.lock_revision(q);
Ok(QuerySnapFut {
fut,
Ok(LspQuerySnapshot {
snap,
analysis,
rev_lock,
})
}
pub fn add_memory_changes(&mut self, event: MemoryEvent) {
self.state.process(Interrupt::Memory(event));
}
pub fn interrupt(&mut self, intr: Interrupt<LspCompilerFeat>) {
if let Interrupt::Compiled(compiled) = &intr {
let proj = self.state.projects().find(|p| p.id == compiled.id);
@ -136,11 +127,6 @@ impl ProjectState {
self.state.process(intr);
}
pub fn change_task(&mut self, task: TaskInputs) {
self.state
.process(Interrupt::ChangeTask(self.state.primary.id.clone(), task));
}
pub(crate) fn stop(&mut self) {
// todo: stop all compilations
}
@ -355,49 +341,15 @@ impl CompileHandler<LspCompilerFeat, ProjectInsStateExt> for CompileHandlerImpl
}
}
pub struct QuerySnapWithStat {
pub fut: QuerySnapFut,
pub(crate) stat: QueryStatGuard,
}
pub type QuerySnapWithStat = (LspQuerySnapshot, QueryStatGuard);
pub struct WorldSnapFut {
rx: oneshot::Receiver<LspCompileSnapshot>,
}
impl WorldSnapFut {
/// wait for the snapshot to be ready
pub async fn receive(self) -> Result<LspCompileSnapshot> {
self.rx
.await
.map_err(map_string_err("failed to get snapshot"))
}
}
pub struct QuerySnapFut {
fut: WorldSnapFut,
analysis: Arc<Analysis>,
rev_lock: AnalysisRevLock,
}
impl QuerySnapFut {
/// wait for the snapshot to be ready
pub async fn receive(self) -> Result<QuerySnap> {
let snap = self.fut.receive().await?;
Ok(QuerySnap {
snap,
analysis: self.analysis,
rev_lock: self.rev_lock,
})
}
}
pub struct QuerySnap {
pub struct LspQuerySnapshot {
pub snap: LspCompileSnapshot,
analysis: Arc<Analysis>,
rev_lock: AnalysisRevLock,
}
impl std::ops::Deref for QuerySnap {
impl std::ops::Deref for LspQuerySnapshot {
type Target = LspCompileSnapshot;
fn deref(&self) -> &Self::Target {
@ -405,7 +357,7 @@ impl std::ops::Deref for QuerySnap {
}
}
impl QuerySnap {
impl LspQuerySnapshot {
pub fn task(mut self, inputs: TaskInputs) -> Self {
self.snap = self.snap.task(inputs);
self

View file

@ -336,7 +336,7 @@ impl ServerState {
type R = CompilerQueryResponse;
assert!(query.fold_feature() != FoldRequestFeature::ContextFreeUnique);
let fut_stat = self.query_snapshot_with_stat(&query)?;
let (mut snap, stat) = self.query_snapshot_with_stat(&query)?;
let input = query
.associated_path()
.map(|path| self.resolve_task_with_state(path.into()))
@ -349,14 +349,13 @@ impl ServerState {
});
just_future(async move {
let mut snap = fut_stat.fut.receive().await?;
// todo: whether it is safe to inherit success_doc with changed entry
if !is_pinning {
if let Some(input) = input {
snap = snap.task(input);
}
}
fut_stat.stat.snap();
stat.snap();
if matches!(query, Completion(..)) {
// Prefetch the package index for completion.

View file

@ -25,8 +25,8 @@ use typst::syntax::Source;
use crate::actor::editor::{EditorActor, EditorRequest};
use crate::project::world::EntryState;
use crate::project::{
update_lock, watch_deps, CompileHandlerImpl, CompileServerOpts, LspInterrupt, ProjectCompiler,
ProjectPreviewState, ProjectState, QuerySnapFut, QuerySnapWithStat, WorldSnapFut,
update_lock, watch_deps, CompileHandlerImpl, CompileServerOpts, LspInterrupt, LspQuerySnapshot,
ProjectCompiler, ProjectPreviewState, ProjectState, QuerySnapWithStat,
PROJECT_ROUTE_USER_ACTION_PRIORITY,
};
use crate::route::ProjectRouteState;
@ -180,12 +180,12 @@ impl ServerState {
}
/// Snapshot the compiler thread for tasks
pub fn snapshot(&mut self) -> Result<WorldSnapFut> {
pub fn snapshot(&mut self) -> Result<LspCompileSnapshot> {
self.project.snapshot()
}
/// Snapshot the compiler thread for language queries
pub fn query_snapshot(&mut self) -> Result<QuerySnapFut> {
pub fn query_snapshot(&mut self) -> Result<LspQuerySnapshot> {
self.project.query_snapshot(None)
}
@ -197,8 +197,8 @@ impl ServerState {
let name: &'static str = q.into();
let path = q.associated_path();
let stat = self.project.stats.query_stat(path, name);
let fut = self.project.query_snapshot(Some(q))?;
Ok(QuerySnapWithStat { fut, stat })
let snap = self.project.query_snapshot(Some(q))?;
Ok((snap, stat))
}
/// Install handlers to the language server.
@ -326,7 +326,6 @@ impl ServerState {
let snap = self.snapshot()?;
just_future(async move {
let snap = snap.receive().await?;
let w = &snap.world;
let info = ServerInfoResponse {
@ -545,7 +544,6 @@ impl ServerState {
let snap = self.snapshot()?;
let task = self.project.export.factory.task();
just_future(async move {
let snap = snap.receive().await?;
let snap = snap.task(TaskInputs {
entry: Some(entry),
..Default::default()

View file

@ -32,11 +32,11 @@ impl Default for QueryStatBucketData {
/// Statistics about some query
#[derive(Default, Clone)]
pub(crate) struct QueryStatBucket {
pub data: Arc<Mutex<QueryStatBucketData>>,
pub struct QueryStatBucket {
pub(crate) data: Arc<Mutex<QueryStatBucketData>>,
}
pub(crate) struct QueryStatGuard {
pub struct QueryStatGuard {
pub bucket: QueryStatBucket,
pub since: std::time::SystemTime,
pub snap_since: OnceLock<std::time::Duration>,