Another attempt at fixing busyReconcile flag

This commit is contained in:
aboyko
2022-08-10 17:11:13 -04:00
parent 6328c43afe
commit cf19355903
2 changed files with 11 additions and 17 deletions

View File

@@ -18,10 +18,12 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
@@ -600,7 +602,7 @@ public final class SimpleLanguageServer implements Sts4LanguageServer, LanguageC
* in a burst. Rather than execute the same request repeatedly we can avoid queuing
* up more requests if the previous request has not yet been started.
*/
private Map<String, CompletableFuture<Void>> reconcileRequests = new ConcurrentHashMap<>();
private Set<String> reconcileRequests = Collections.synchronizedSet(new HashSet<>());
private DiagnosticSeverityProvider severityProvider = DiagnosticSeverityProvider.DEFAULT;
@@ -616,21 +618,14 @@ public final class SimpleLanguageServer implements Sts4LanguageServer, LanguageC
return;
}
if (reconcileRequests.isEmpty()) {
busyReconcile = new CompletableFuture<>();
}
String uri = docId.getUri();
CompletableFuture<Void> newFuture = new CompletableFuture<Void>();
CompletableFuture<Void> oldFuture = reconcileRequests.putIfAbsent(uri, newFuture);
if (oldFuture != null && oldFuture != newFuture) {
if (!reconcileRequests.add(uri)) {
log.debug("Reconcile skipped {}", uri);
return;
}
CompletableFuture<Void> reconcileSession = oldFuture == null ? newFuture : oldFuture;
// Log.debug("Reconciling BUSY");
CompletableFuture<Void> 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
@@ -710,10 +705,7 @@ public final class SimpleLanguageServer implements Sts4LanguageServer, LanguageC
return Mono.empty();
})
.doFinally(ignore -> {
reconcileSession.complete(null);
if (reconcileRequests.isEmpty()) {
busyReconcile.complete(null);
}
currentSession.complete(null);
// Log.debug("Reconciler DONE : "+this.busyReconcile.isDone());
})
.subscribe();

View File

@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2016, 2019 Pivotal, Inc.
* Copyright (c) 2016, 2022 Pivotal, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -4806,14 +4806,16 @@ public class ConcourseEditorTest {
@Test public void reconcilerRaceCondition() throws Exception {
SynchronizationPoint reconcilerThreadStart = harness.reconcilerThreadStart();
System.out.println("Reconcile thread started");
Editor editor = harness.newEditor("garbage");
reconcilerThreadStart.reached(); // Blocks until the reconciler thread is reached.
System.out.println("Editor created");
try {
String editorContents = editor.getRawText();
for (int i = 0; i < 4; i++) {
System.out.println("Perfroming change: " + i);
editorContents = "\n" +editorContents;
editor.setText(editorContents);
System.out.println("Text changed: " + i);
}
} finally {
reconcilerThreadStart.unblock();