Attempted fix of suspected deadlock

See: https://github.com/spring-projects/sts4/issues/136
This commit is contained in:
Kris De Volder
2018-11-21 13:49:30 -08:00
parent 8f39484733
commit 7ffbe07008
7 changed files with 87 additions and 87 deletions

View File

@@ -217,7 +217,7 @@ public class BootJavaLanguageServerComponents implements LanguageServerComponent
});
server.onInitialize(this::initialize);
server.onInitialized(this::initialized);
server.doOnInitialized(this::initialized);
server.onShutdown(this::shutdown);
}

View File

@@ -11,9 +11,10 @@
package org.springframework.ide.vscode.boot.jdt.ls;
import reactor.core.Disposable;
import reactor.core.publisher.Mono;
public interface InitializableJavaProjectsService extends JavaProjectsService {
Disposable initialize() throws Exception;
Mono<Disposable> initialize();
}

View File

@@ -28,10 +28,10 @@ import com.google.common.base.Suppliers;
import reactor.core.Disposable;
public class JavaProjectsServiceWithFallback implements JavaProjectsService {
private Logger log = LoggerFactory.getLogger(JavaProjectsServiceWithFallback.class);
final private CompletableFuture<Void> initialized = new CompletableFuture<Void>();
final private CompletableFuture<Disposable> mainServiceInitialized;
final private SimpleLanguageServer server;
private Supplier<JavaProjectsService> fallback;
@@ -42,30 +42,22 @@ public class JavaProjectsServiceWithFallback implements JavaProjectsService {
this.main = main;
this.fallback = Suppliers.memoize(fallback);
this.server = server;
CompletableFuture<Disposable> disposable = new CompletableFuture<Disposable>();
this.server.onInitialized(() -> {
try {
disposable.complete(main.initialize());
initialized.complete(null);
} catch (Throwable e) {
log.info("Fallback classpath provider will be enabled");
disposable.complete(()-> {});
initialized.completeExceptionally(e);
}
});
this.server.onShutdown(() ->
disposable.thenAccept(Disposable::dispose).join()
this.mainServiceInitialized = this.server
.onInitialized(main.initialize())
.toFuture();
this.server.onShutdown(() ->
mainServiceInitialized.thenAccept(Disposable::dispose).join()
);
}
@Override
public Optional<IJavaProject> find(TextDocumentIdentifier doc) {
if (initialized.isDone()) {
if (initialized.isCompletedExceptionally()) {
if (mainServiceInitialized.isDone()) {
if (mainServiceInitialized.isCompletedExceptionally()) {
return fallback.get().find(doc);
} else {
return main.find(doc);
}
}
} else {
log.debug("find => NOT INITIALIZED YET");
}
@@ -75,7 +67,7 @@ public class JavaProjectsServiceWithFallback implements JavaProjectsService {
@Override
public void addListener(Listener listener) {
initialized.handle((success, failed) -> {
mainServiceInitialized.handle((success, failed) -> {
if (failed!=null) {
fallback.get().addListener(listener);
} else {
@@ -87,7 +79,7 @@ public class JavaProjectsServiceWithFallback implements JavaProjectsService {
@Override
public void removeListener(Listener listener) {
initialized.handle((success, failed) -> {
mainServiceInitialized.handle((success, failed) -> {
if (failed!=null) {
fallback.get().removeListener(listener);
} else {
@@ -99,12 +91,12 @@ public class JavaProjectsServiceWithFallback implements JavaProjectsService {
@Override
public IJavadocProvider javadocProvider(String projectUri, CPE classpathEntry) {
if (initialized.isDone()) {
if (initialized.isCompletedExceptionally()) {
if (mainServiceInitialized.isDone()) {
if (mainServiceInitialized.isCompletedExceptionally()) {
return fallback.get().javadocProvider(projectUri, classpathEntry);
} else {
return main.javadocProvider(projectUri, classpathEntry);
}
}
} else {
log.debug("javadoc => NOT INITIALIZED YET");
}

View File

@@ -38,6 +38,7 @@ import org.springframework.ide.vscode.commons.util.FileObserver;
import org.springframework.ide.vscode.commons.util.UriUtil;
import reactor.core.Disposable;
import reactor.core.publisher.Mono;
public class JdtLsProjectCache implements InitializableJavaProjectsService {
@@ -163,45 +164,43 @@ public class JdtLsProjectCache implements InitializableJavaProjectsService {
}
@Override
public Disposable initialize() throws Exception {
try {
return server.addClasspathListener(new ClasspathListener() {
@Override
public void changed(Event event) {
log.debug("claspath event received {}", event);
server.onInitialized(() -> {
//log.info("initialized.thenRun block entered");
try {
synchronized (table) {
String uri = UriUtil.normalize(event.projectUri);
log.debug("uri = {}", uri);
if (event.deleted) {
log.debug("event.deleted = true");
JavaProject deleted = table.remove(uri);
if (deleted!=null) {
log.debug("removed from table = true");
notifyDelete(deleted);
} else {
log.warn("Deleted project not removed because uri {} not found in {}", uri, table.keySet());
}
public Mono<Disposable> initialize() {
return server.addClasspathListener(new ClasspathListener() {
@Override
public void changed(Event event) {
log.debug("claspath event received {}", event);
server.doOnInitialized(() -> {
//log.info("initialized.thenRun block entered");
try {
synchronized (table) {
String uri = UriUtil.normalize(event.projectUri);
log.debug("uri = {}", uri);
if (event.deleted) {
log.debug("event.deleted = true");
JavaProject deleted = table.remove(uri);
if (deleted!=null) {
log.debug("removed from table = true");
notifyDelete(deleted);
} else {
log.debug("deleted = false");
JavaProject newProject = new JavaProject(getFileObserver(), new URI(uri), new ClasspathData(event.name, event.classpath.getEntries()), JdtLsProjectCache.this);
JavaProject oldProject = table.put(uri, newProject);
if (oldProject != null) {
notifyChanged(newProject);
} else {
notifyCreated(newProject);
}
log.warn("Deleted project not removed because uri {} not found in {}", uri, table.keySet());
}
} else {
log.debug("deleted = false");
JavaProject newProject = new JavaProject(getFileObserver(), new URI(uri), new ClasspathData(event.name, event.classpath.getEntries()), JdtLsProjectCache.this);
JavaProject oldProject = table.put(uri, newProject);
if (oldProject != null) {
notifyChanged(newProject);
} else {
notifyCreated(newProject);
}
}
} catch (Exception e) {
log.error("", e);
}
});
}
});
} catch (Throwable t) {
} catch (Exception e) {
log.error("", e);
}
});
}
}).doOnError(t -> {
if (isNoJdtError(t)) {
log.info("JDT Language Server not available. Fallback classpath provider will be used instead.");
} else if (isOldJdt(t)) {
@@ -209,7 +208,6 @@ public class JdtLsProjectCache implements InitializableJavaProjectsService {
} else {
log.error("Unexpected error registering classpath listener with JDT. Fallback classpath provider will be used instead.", t);
}
throw t;
}
});
}
}