Skip to content

Conversation

@lionel-
Copy link
Contributor

@lionel- lionel- commented May 17, 2024

Branched from #358.

This PR is a preparation for the next one where I remove diagnostics_id from Document. This value is used in a debouncing mechanism for diagnostics which relies on mutex synchronisation of documents. The mutex needs to go away to make the WorldState a pure, non-mutable value.

I saw in a comment that the debouncer is motivated by the fact that it queries the current state of the search path via an r_task() which we don't want to do too aggressively. So this PR removes this concurrent r_task(), this way we won't need the debouncer and the mutable documents. In the new approach we send the console scopes from ReadConsole, after each top-level evaluation. This makes the design cleaner and we don't need to query R as often.

Progress towards #691 (Reduce concurrent R evaluations to a minimum): Querying the search path concurrently with R was unsafe I think, we might be in the middle of an attach() or similar. We don't want to know the state of the search path in the middle of a computation, we want to know its state between top-level evaluations.

Progress towards posit-dev/positron#3180 (Decouple LSP from the kernel): Sending the console scopes from read-console also brings us closer to decoupling the LSP from the kernel. We send the scopes via a Rust channel but it might just as well be a Jupyter comm.

Copy link
Contributor

@DavisVaughan DavisVaughan left a comment

Choose a reason for hiding this comment

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

Very exciting!

Comment on lines +1299 to +1305
// Get the set of installed packages
let installed_packages: Vec<String> = RFunction::new("base", ".packages")
.param("all.available", true)
.call()?
.try_into()?;
Copy link
Contributor

Choose a reason for hiding this comment

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

I am a bit worried that calling .packages() on each read_console() iteration is a little too expensive (particularly with things like network drives on Windows)

With the diagnostics IIUC it was only calling .packages() once diagnostics were actually being fired, which was on that 1 second cancellable delay once the user stopped doing anything.

Copy link
Contributor

Choose a reason for hiding this comment

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

If we aren't already doing caching in a downstream PR, I think we should before merging

Copy link
Contributor Author

@lionel- lionel- May 29, 2024

Choose a reason for hiding this comment

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

Ideally the LSP would scan the active libpaths to determine this and get update events.

I was thinking one query per top-level-command is alright until then. Are you worried about the case of someone doing Cmd+Enter very quickly? Or about someone running a notebook from top to bottom? In many cases the computation of the chunk will dominate .packages(), e.g. large data manipulations, large plots, large models computation. So I'm not sure we need to address this urgently.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The thing is that I'm not sure how we could cache this without watching the folders to trigger invalidation? Can you think of another way? I'd prefer not get into fs watching right now.

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see an easy alternative right now either, we can keep it as is for now

_ => {},
});

r_task(|| unsafe {
Copy link
Contributor

Choose a reason for hiding this comment

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

Super nice to be able to remove this. I've been thinking about how to do this for awhile now!

}

fn generate_diagnostics(doc: &Document) -> Vec<Diagnostic> {
fn generate_diagnostics(doc: &Document, state: &WorldState) -> Vec<Diagnostic> {
Copy link
Contributor

Choose a reason for hiding this comment

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

It is neat to think about the fact that this could all eventually be running as a "long running task" and get its own free floating copy of WorldState without having to worry about interior mutability. That sounds quite nice.

Copy link
Contributor Author

@lionel- lionel- May 29, 2024

Choose a reason for hiding this comment

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

stay tuned for the next PRs! 😀

@lionel- lionel- force-pushed the feature/lsp-state branch from 6e31619 to ed7d32f Compare May 29, 2024 09:22
Base automatically changed from feature/lsp-state to main May 29, 2024 09:25
@lionel- lionel- force-pushed the feature/read-console-scopes branch 2 times, most recently from d2185a6 to 0853dea Compare May 29, 2024 11:03
@lionel- lionel- force-pushed the feature/read-console-scopes branch from 2592ffd to 0bf4766 Compare May 30, 2024 08:00
@lionel- lionel- merged commit 8f1d49e into main May 30, 2024
@lionel- lionel- deleted the feature/read-console-scopes branch May 30, 2024 08:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants