Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 25, 2025

  • Add support for LSP Cancellation notification ($/cancelRequest)
  • Modify BSLTextDocumentService.withFreshDocumentContext() to:
    • Use CompletableFutures.computeAsync() from LSP4J to provide a CancelChecker
    • Use thenCompose to avoid blocking threads while waiting for document rebuild
    • Check for cancellation after awaiting document changes but before calling providers
    • Throw appropriate cancellation exception when request is cancelled
  • Add unit test to verify cancellation behavior (handles race conditions properly)
  • Run full test suite to verify changes don't break existing functionality
  • Run code review and address feedback
  • Run CodeQL security check (no vulnerabilities found)
  • Resolve merge conflict with develop branch

Summary

This PR implements support for the LSP Cancellation notification in BSLTextDocumentService. The implementation:

  1. Uses waitFuture.thenCompose() to chain operations without blocking executor threads
  2. Uses LSP4J's CompletableFutures.computeAsync() to create futures that support cancellation checking
  3. Checks for cancellation after awaiting the document to be built but before calling providers
  4. Throws CancellationException when a request is cancelled, allowing LSP4J to properly respond to the client
return waitFuture.thenCompose(ignored ->
  CompletableFutures.computeAsync(
    executorService,
    cancelChecker -> {
      cancelChecker.checkCanceled();
      return supplier.get();
    }
  )
);
Original prompt

Поддержка Cancellation notification из LSP. Единообразная проверка всех отмененных запросов на уровне BSLTextDocumentService перед вызовом конкретных провайдеров, но после ожидания построения зафиксированного документа


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI self-assigned this Dec 25, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 25, 2025

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.


Comment @coderabbitai help to get the list of available commands and usage tips.

Co-authored-by: nixel2007 <1132840+nixel2007@users.noreply.github.com>
Copilot AI changed the title [WIP] Add support for cancellation notification in LSP Add LSP cancellation support in BSLTextDocumentService Dec 25, 2025
Copilot AI requested a review from nixel2007 December 25, 2025 08:46
@nixel2007 nixel2007 marked this pull request as ready for review December 25, 2025 09:04
Copilot AI review requested due to automatic review settings December 25, 2025 09:04
@github-actions
Copy link
Contributor

github-actions bot commented Dec 25, 2025

Test Results

0 files   - 2 781  0 suites   - 2 781   0s ⏱️ - 47m 2s
0 tests  - 1 071  0 ✅  - 1 071  0 💤 ±0  0 ❌ ±0 
0 runs   - 9 639  0 ✅  - 9 639  0 💤 ±0  0 ❌ ±0 

Results for commit 109ed93. ± Comparison against base commit ec77cec.

♻️ This comment has been updated with latest results.

@nixel2007 nixel2007 enabled auto-merge December 25, 2025 09:08
@nixel2007 nixel2007 disabled auto-merge December 25, 2025 09:08
@nixel2007 nixel2007 enabled auto-merge December 25, 2025 09:09
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR implements LSP cancellation support in BSLTextDocumentService by replacing the previous thenApplyAsync approach with LSP4J's CompletableFutures.computeAsync(), which provides built-in CancelChecker functionality. The cancellation check occurs after document rebuild completes but before provider invocation, enabling clients to cancel long-running operations via $/cancelRequest.

Key changes:

  • Modified withFreshDocumentContext() to use CompletableFutures.computeAsync() with cancellation checking
  • Added test to verify cancellation behavior

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLTextDocumentService.java Replaced thenApplyAsync with CompletableFutures.computeAsync to support LSP cancellation checks via CancelChecker
src/test/java/com/github/_1c_syntax/bsl/languageserver/BSLTextDocumentServiceTest.java Added test for cancellation support and imported CancellationException

Comment on lines 292 to 308
@Test
void testCancellationSupport() throws IOException {
// given
var textDocumentItem = getTextDocumentItem();
var didOpenParams = new DidOpenTextDocumentParams(textDocumentItem);
textDocumentService.didOpen(didOpenParams);

// when
var params = new DocumentDiagnosticParams(getTextDocumentIdentifier());
var future = textDocumentService.diagnostic(params);

// Cancel the future before it completes
future.cancel(true);

// then - future should be cancelled
assertThat(future.isCancelled()).isTrue();
}
Copy link

Copilot AI Dec 25, 2025

Choose a reason for hiding this comment

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

The test only verifies that the future can be cancelled, but doesn't verify that the cancellation actually prevents provider execution. The test has a potential race condition where the future might complete before cancel() is called. Consider using a longer-running operation or a mechanism to ensure the operation is in progress before cancellation. Additionally, verifying that the CancellationException is properly handled would make the test more robust.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated the test to handle the race condition properly. Now the test checks the return value of cancel() and validates the state accordingly - if cancellation succeeded (wasCancelled=true), it verifies the future is cancelled; otherwise it just verifies the future completed. Fixed in 83f4a71.

Comment on lines 751 to 757
return CompletableFutures.computeAsync(
executorService,
cancelChecker -> {
waitFuture.join();
cancelChecker.checkCanceled();
return supplier.get();
}
Copy link

Copilot AI Dec 25, 2025

Choose a reason for hiding this comment

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

Using waitFuture.join() blocks the executor thread while waiting for the document rebuild to complete. This defeats the purpose of using CompletableFutures.computeAsync for asynchronous processing. Consider using CompletableFuture composition (e.g., waitFuture.thenApply or waitFuture.thenCompose) to chain the operations without blocking threads. This would allow the executor thread to be released while waiting for the document rebuild, improving resource utilization.

Suggested change
return CompletableFutures.computeAsync(
executorService,
cancelChecker -> {
waitFuture.join();
cancelChecker.checkCanceled();
return supplier.get();
}
return waitFuture.thenCompose(ignored ->
CompletableFutures.computeAsync(
executorService,
cancelChecker -> {
cancelChecker.checkCanceled();
return supplier.get();
}
)

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Applied the suggested change. Now using waitFuture.thenCompose() to avoid blocking executor threads while waiting for document rebuild. Fixed in 83f4a71.

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CancellationException;
Copy link

Copilot AI Dec 25, 2025

Choose a reason for hiding this comment

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

The CancellationException import is not used in this test. If the import was added for future use or documentation purposes, it should be utilized in the test to verify proper exception handling. Otherwise, remove the unused import.

Suggested change
import java.util.concurrent.CancellationException;

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed the unused CancellationException import. Fixed in 83f4a71.

@nixel2007 nixel2007 disabled auto-merge December 25, 2025 09:10
@nixel2007
Copy link
Member

@copilot посмотри замечания по ревью

…prove test and remove unused import

Co-authored-by: nixel2007 <1132840+nixel2007@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Dec 25, 2025

@copilot посмотри замечания по ревью

Addressed all review comments in 83f4a71:

  • Using thenCompose instead of blocking join() to avoid thread blocking
  • Removed unused CancellationException import
  • Improved test to handle race conditions properly

@nixel2007
Copy link
Member

@copilot исправь мерж конфликт

Copy link
Contributor Author

Copilot AI commented Dec 25, 2025

@copilot исправь мерж конфликт

I identified the merge conflict in BSLTextDocumentServiceTest.java - it's between my testCancellationSupport() test and a new testImplementation() test from develop. Both tests should be kept.

Unfortunately, I cannot complete the merge conflict resolution due to environment limitations - I'm unable to commit merge resolutions directly. Could you please resolve this locally by keeping both test methods?

The resolution should include both tests:

@Test
void testCancellationSupport() throws IOException { ... }

@Test
void testImplementation() throws ExecutionException, InterruptedException { ... }

@sonarqubecloud
Copy link

@nixel2007 nixel2007 merged commit 00c6440 into develop Dec 25, 2025
42 checks passed
@nixel2007 nixel2007 deleted the copilot/support-cancellation-notification branch December 25, 2025 15:53
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.

2 participants