Skip to content

Run long-spanning tasks cancellably on background in the (Java) LSP server. #7708

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

lahodaj
Copy link
Contributor

@lahodaj lahodaj commented Aug 29, 2024

@jtulach reported the code completion inside VS Code is sometimes slow for him. I was thinking of that, and experimenting, and I think at least part of the problem is that tasks that should be background tasks are not properly cancellable in the VS Code (Java) server.

I was doing experiments on:
https://github.com/openjdk/jdk/blob/master/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java

and it seemed there were two (current) particular pain points:

  • diagnostics (especially hints) computation, which can take a fairly long time to compute
  • semantic coloring computation, which can also take some time to compute

Neither of these can be cancelled when the request to compute code completion. This draft is attempting to improve that, and run diagnostics and semantic coloring in a cancellable way.

It only properly cancels for Java sources at this time, for other sources runs only the CompletableFuture cancel will work. Some work on Schedulers will be needed to fully enable this for non-Java sources, but I suspect this can wait

I also have a separate PR that adds additional logging for code completion:
#7815

@lahodaj
Copy link
Contributor Author

lahodaj commented Oct 9, 2024

I think we need to make progress on this.

@lahodaj lahodaj marked this pull request as ready for review October 9, 2024 13:55
@lahodaj lahodaj added Java [ci] enable extra Java tests (java.completion, java.source.base, java.hints, refactoring.java, form) LSP [ci] enable Language Server Protocol tests VSCode Extension [ci] enable VSCode Extension tests labels Oct 9, 2024
@lahodaj lahodaj added this to the NB24 milestone Oct 9, 2024
@apache apache locked and limited conversation to collaborators Oct 9, 2024
@apache apache unlocked this conversation Oct 9, 2024
@lahodaj lahodaj changed the title Prototype: run long-spanning tasks cancellably on background in the (Java) LSP server. Run long-spanning tasks cancellably on background in the (Java) LSP server. Oct 9, 2024
@lahodaj lahodaj requested review from dbalek and sdedic October 9, 2024 14:15
@ebarboni ebarboni modified the milestones: NB24, NB25 Oct 22, 2024
@lahodaj lahodaj force-pushed the java-lsp-server-compute-long-spanning-tasks-cancellably-on-background branch from a768cee to 71e959b Compare November 29, 2024 14:12
@lahodaj
Copy link
Contributor Author

lahodaj commented Nov 29, 2024

FWIW: I've changed the implementation to an explicit priority "queue", as the original patch with injecting tasks in the editor background infrastructure proved to be too complex, at least for now.

@lahodaj lahodaj force-pushed the java-lsp-server-compute-long-spanning-tasks-cancellably-on-background branch from 49bb7f8 to a7f0d23 Compare December 3, 2024 10:08
@lahodaj
Copy link
Contributor Author

lahodaj commented Dec 3, 2024

I limitation of this way to cancel things is that it cannot stop computations inside javac/parser. Unlike the previous round which used the "editor" tasks, which can stop even javac/parser.

But, this patch:

  • should provide an improvement compared to the current state
  • should allow various features use the abstraction - and then we might be able to improve the abstraction, without (significantly) re-writing the features.

Copy link
Contributor

@eirikbakke eirikbakke left a comment

Choose a reason for hiding this comment

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

Just passing by with some comments/questions... I'm not very familiar with this area in the codebase.

public void cancel();
}

public final class CancelCheck {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this supposed to be a public class? It is currently used only within this class.

}

public void registerCancel(CancelCallback callback) {
cancelCallback.set(callback);
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps throw an IllegalStateException if a callback is already registered.

void cancel() {
cancelled.set(true);

CancelCallback callback = cancelCallback.get();
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be easier to verify the thread-safety of these methods if the accesses to cancelled and cancelCallback were synchronized as a unit, rather than just being individually protected by AtomicBoolean/AtomicReference.

But in practice I assume registerCancel is going to be called up-front, before concurrent accesses start.

private final P data;
private final CompletableFuture<R> result;

public TaskDescription(CancellableTask<P, R> task, P data, CompletableFuture<R> result) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps add null checks on parameters so that NPEs happen immediately and with a useful stack trace, rather than with a delay.


private CancelCheck() {}

public boolean isCancelled() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't this be called somewhere from TextDocumentServiceImpl? Whenever I do cancelable operations, I usually have a loop of batch operations with an if (isCanceled()) break; somewhere.

@ebarboni ebarboni modified the milestones: NB25, NB26 Jan 24, 2025
@neilcsmith-net neilcsmith-net modified the milestones: NB26, NB27 Apr 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Java [ci] enable extra Java tests (java.completion, java.source.base, java.hints, refactoring.java, form) LSP [ci] enable Language Server Protocol tests VSCode Extension [ci] enable VSCode Extension tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants