Skip to content

Commit

Permalink
fix: don't log IndexNotReadyException / ReadAction.CannotReadException
Browse files Browse the repository at this point in the history
error when attempt is not reached

Signed-off-by: azerr <[email protected]>
  • Loading branch information
angelozerr committed Aug 2, 2023
1 parent 7ffb092 commit 99ba692
Showing 1 changed file with 42 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,33 @@ public class LSPCompletableFuture<R> extends CompletableFuture<R> {

private static final Logger LOGGER = LoggerFactory.getLogger(LSPCompletableFuture.class);

private class ResultOrError<R> {

public final R result;

public final Exception error;

public ResultOrError(R result, Exception error) {
this.result = result;
this.error = error;
}
}

private static final int MAX_ATTEMPT = 5;
private final Function<ProgressIndicator, R> code;
private final IndexAwareLanguageClient languageClient;
private final String progressTitle;
private final AtomicInteger nbAttempt;
private CancellablePromise<R> nonBlockingReadActionPromise;
private CancellablePromise<ResultOrError<R>> nonBlockingReadActionPromise;

public LSPCompletableFuture(Function<ProgressIndicator, R> code, String progressTitle, IndexAwareLanguageClient languageClient) {
this.code = code;
this.progressTitle = progressTitle;
this.languageClient = languageClient;
this.nbAttempt = new AtomicInteger(0);
// if indexation is processing, we need to execute the promise in smart mode
var executeInmartMode = DumbService.getInstance(languageClient.getProject()).isDumb();
var promise = nonBlockingReadActionPromise( executeInmartMode);
var executeInSmartMode = DumbService.getInstance(languageClient.getProject()).isDumb();
var promise = nonBlockingReadActionPromise(executeInSmartMode);
bind(promise);
}

Expand All @@ -60,15 +72,27 @@ public LSPCompletableFuture(Function<ProgressIndicator, R> code, String progress
*
* @param promise the promise which will execute the function code in a non blocking read action context
*/
private void bind(CancellablePromise<R> promise) {
private void bind(CancellablePromise<ResultOrError<R>> promise) {
this.nonBlockingReadActionPromise = promise;
// On error...
promise.onError(ex -> {
if (ex instanceof IndexNotReadyException || ex instanceof ReadAction.CannotReadException) {
if (ex instanceof ProcessCanceledException || ex instanceof CancellationException) {
// Case 2: cancel the completable future
this.cancel(true);
} else {
// Other case..., mark the completable future as error
this.completeExceptionally(ex);
}
});
// On success...
promise.onSuccess(value -> {
if (value.error != null) {
Exception ex = value.error;
// There were an error with IndexNotReadyException or ReadAction.CannotReadException
// Case 1: Attempt to retry the start of the promise
if (nbAttempt.incrementAndGet() >= MAX_ATTEMPT) {
// 1.1 Maximum number reached, mark the completable future as error
LOGGER.warn("Maximum number (" + MAX_ATTEMPT + ")" + " of attempts to start non blocking read action for '" + progressTitle + "' has been reached", ex);
LOGGER.warn("Maximum number (" + MAX_ATTEMPT + ")" + " of attempts to start non blocking read action for '" + progressTitle + "' has been reached", ex);
this.completeExceptionally(new ExecutionAttemptLimitReachedException(progressTitle, MAX_ATTEMPT, ex));
} else {
// Retry ...
Expand All @@ -77,35 +101,36 @@ private void bind(CancellablePromise<R> promise) {
var newPromise = nonBlockingReadActionPromise(true);
bind(newPromise);
}
} else if (ex instanceof ProcessCanceledException || ex instanceof CancellationException) {
// Case 2: cancel the completable future
this.cancel(true);
} else {
// Other case..., mark the completable future as error
this.completeExceptionally(ex);
this.complete(value.result);
}
});
// On success...
promise.onSuccess(value -> this.complete(value));
}

/**
* Create a non blocking read action promise.
*
* @param executeInSmartMode true if the promise must be executed in smart mode and false otherwise.
*
* @return a non blocking read action promise
*/
@NotNull
private CancellablePromise<R> nonBlockingReadActionPromise(boolean executeInSmartMode ) {
private CancellablePromise<ResultOrError<R>> nonBlockingReadActionPromise(boolean executeInSmartMode) {
var project = languageClient.getProject();

var indicator = new LSPProgressIndicator(languageClient);
indicator.setText(progressTitle);
var action = ReadAction.nonBlocking(() -> code.apply(indicator))
var action = ReadAction.nonBlocking(() ->
{
try {
R result = code.apply(indicator);
return new ResultOrError<R>(result, null);
} catch (IndexNotReadyException | ReadAction.CannotReadException e) {
return new ResultOrError<R>(null, e);
}
})
.wrapProgress(indicator)
.expireWith(languageClient); // promise is canceled when language client is stopped
if ( executeInSmartMode ) {
if (executeInSmartMode) {
action = action.inSmartMode(project);
}
return action
Expand Down

0 comments on commit 99ba692

Please sign in to comment.