From 1515345659cfb5fa289871ff40e359906c49bd2e Mon Sep 17 00:00:00 2001 From: Kris De Volder Date: Wed, 10 Aug 2022 16:15:36 -0700 Subject: [PATCH 1/2] One more try to fix deadlock in concourse test cases --- .../commons/languageserver/util/SimpleLanguageServer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleLanguageServer.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleLanguageServer.java index 7c7046991..7379acfa5 100644 --- a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleLanguageServer.java +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleLanguageServer.java @@ -630,7 +630,7 @@ public final class SimpleLanguageServer implements Sts4LanguageServer, LanguageC // in long "hangs" for slow reconcile providers Mono mono = props.getReconcileDelay() > 0 ? Mono.delay(Duration.ofMillis(props.getReconcileDelay())).publishOn(RECONCILER_SCHEDULER) - : Mono.empty().publishOn(RECONCILER_SCHEDULER); + : Mono.empty().subscribeOn(RECONCILER_SCHEDULER); mono.then(Mono.fromRunnable(() -> { reconcileRequests.remove(uri); From 45a3c7f702702ec2c336cf548775aa9805cce2a1 Mon Sep 17 00:00:00 2001 From: Kris De Volder Date: Wed, 10 Aug 2022 16:45:22 -0700 Subject: [PATCH 2/2] One more try to fix deadlock Suspect that `Mono.empty().subscribeOn` is just not working properly. So just avoid using it. --- .../util/SimpleLanguageServer.java | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleLanguageServer.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleLanguageServer.java index 7379acfa5..ceb0da624 100644 --- a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleLanguageServer.java +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleLanguageServer.java @@ -625,14 +625,9 @@ public final class SimpleLanguageServer implements Sts4LanguageServer, LanguageC } // Log.debug("Reconciling BUSY"); - CompletableFuture currentSession = this.busyReconcile = new CompletableFuture<>(); - // Avoid running in the same thread as lsp4j as it can result - // in long "hangs" for slow reconcile providers - Mono mono = props.getReconcileDelay() > 0 - ? Mono.delay(Duration.ofMillis(props.getReconcileDelay())).publishOn(RECONCILER_SCHEDULER) - : Mono.empty().subscribeOn(RECONCILER_SCHEDULER); + CompletableFuture currentSession = this.busyReconcile = new CompletableFuture<>(); - mono.then(Mono.fromRunnable(() -> { + Mono doReconcile = Mono.fromRunnable(() -> { reconcileRequests.remove(uri); log.debug("Reconcile starting {}", uri); @@ -699,7 +694,7 @@ public final class SimpleLanguageServer implements Sts4LanguageServer, LanguageC }; engine.reconcile(doc, problems); - })) + }) .onErrorResume(error -> { log.error("", error); return Mono.empty(); @@ -707,8 +702,18 @@ public final class SimpleLanguageServer implements Sts4LanguageServer, LanguageC .doFinally(ignore -> { currentSession.complete(null); // Log.debug("Reconciler DONE : "+this.busyReconcile.isDone()); - }) - .subscribe(); + }); + + // Use RECONCILER_SCHEDULER to avoid running in the same thread as lsp4j as it can result + // in long "hangs" for slow reconcile providers + if (props.getReconcileDelay() > 0) { + Mono.delay(Duration.ofMillis(props.getReconcileDelay())) + .publishOn(RECONCILER_SCHEDULER) + .then(doReconcile) + .subscribe(); + } else { + doReconcile.subscribeOn(RECONCILER_SCHEDULER).subscribe(); + } } public DiagnosticSeverity getDiagnosticSeverity(ReconcileProblem problem) {