fix threading issue with project listener registration by introducing a delegate in between the involved parties
This commit is contained in:
committed by
BoykoAlex
parent
d9905c40ce
commit
fdeb1dd55c
@@ -81,16 +81,19 @@ public class SpringLiveHoverWatchdog {
|
||||
|
||||
@Override
|
||||
public void deleted(IJavaProject project) {
|
||||
logger.info("project deleted event: {}", project.getElementName());
|
||||
refreshEnablement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void created(IJavaProject project) {
|
||||
logger.info("project created event: {}", project.getElementName());
|
||||
refreshEnablement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changed(IJavaProject project) {
|
||||
logger.info("project changed event: {}", project.getElementName());
|
||||
refreshEnablement();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -79,19 +79,19 @@ public class SpringSymbolIndex {
|
||||
private final Listener projectListener = new Listener() {
|
||||
@Override
|
||||
public void created(IJavaProject project) {
|
||||
log.debug("project created event: {}", project.getElementName());
|
||||
log.info("project created event: {}", project.getElementName());
|
||||
initializeProject(project);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changed(IJavaProject project) {
|
||||
log.debug("project changed event: {}", project.getElementName());
|
||||
log.info("project changed event: {}", project.getElementName());
|
||||
initializeProject(project);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleted(IJavaProject project) {
|
||||
log.debug("project deleted event: {}", project.getElementName());
|
||||
log.info("project deleted event: {}", project.getElementName());
|
||||
deleteProject(project);
|
||||
}
|
||||
};
|
||||
@@ -146,6 +146,7 @@ public class SpringSymbolIndex {
|
||||
|
||||
if (getProjectObserver() != null) {
|
||||
getProjectObserver().addListener(projectListener);
|
||||
log.info("project listener registered");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.jdt.ls;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@@ -33,20 +35,52 @@ public class JavaProjectsServiceWithFallback implements JavaProjectsService {
|
||||
|
||||
private Logger log = LoggerFactory.getLogger(JavaProjectsServiceWithFallback.class);
|
||||
|
||||
final private CompletableFuture<Disposable> mainServiceInitialized;
|
||||
private final CompletableFuture<Disposable> mainServiceInitialized;
|
||||
|
||||
final private SimpleLanguageServer server;
|
||||
private Supplier<JavaProjectsService> fallback;
|
||||
final private InitializableJavaProjectsService main;
|
||||
private final SimpleLanguageServer server;
|
||||
private final Supplier<JavaProjectsService> fallback;
|
||||
private final InitializableJavaProjectsService main;
|
||||
|
||||
private final Listener listenerDelegate;
|
||||
private final List<Listener> listeners;
|
||||
|
||||
public JavaProjectsServiceWithFallback(SimpleLanguageServer server, InitializableJavaProjectsService main, Supplier<JavaProjectsService> fallback) {
|
||||
Assert.isNotNull(fallback);
|
||||
this.main = main;
|
||||
this.fallback = Suppliers.memoize(fallback);
|
||||
this.fallback = Suppliers.memoize(new Supplier<JavaProjectsService>() {
|
||||
@Override
|
||||
public JavaProjectsService get() {
|
||||
JavaProjectsService fallbackService = fallback.get();
|
||||
fallbackService.addListener(listenerDelegate);
|
||||
return fallbackService;
|
||||
}
|
||||
});
|
||||
|
||||
this.server = server;
|
||||
this.listeners = new ArrayList<>();
|
||||
|
||||
this.listenerDelegate = new Listener() {
|
||||
@Override
|
||||
public void deleted(IJavaProject project) {
|
||||
notifyDelete(project);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void created(IJavaProject project) {
|
||||
notifyCreated(project);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changed(IJavaProject project) {
|
||||
notifyChanged(project);
|
||||
}
|
||||
};
|
||||
this.main.addListener(this.listenerDelegate);
|
||||
|
||||
this.mainServiceInitialized = this.server
|
||||
.onInitialized(main.initialize())
|
||||
.toFuture();
|
||||
|
||||
this.server.onShutdown(() -> {
|
||||
try {
|
||||
if (!mainServiceInitialized.isCompletedExceptionally()) {
|
||||
@@ -62,6 +96,50 @@ public class JavaProjectsServiceWithFallback implements JavaProjectsService {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(Listener listener) {
|
||||
synchronized (listeners) {
|
||||
listeners.add(listener);
|
||||
log.info("added listener - now listeners registered: " + listeners.size());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(Listener listener) {
|
||||
synchronized (listeners) {
|
||||
listeners.remove(listener);
|
||||
log.info("removed listener - now listeners registered: " + listeners.size());
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyCreated(IJavaProject newProject) {
|
||||
log.info("Project created: " + newProject.getLocationUri());
|
||||
|
||||
synchronized (listeners) {
|
||||
for (Listener listener : listeners) {
|
||||
listener.created(newProject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyDelete(IJavaProject deleted) {
|
||||
log.info("Project deleted: " + deleted.getLocationUri());
|
||||
synchronized (listeners) {
|
||||
for (Listener listener : listeners) {
|
||||
listener.deleted(deleted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyChanged(IJavaProject project) {
|
||||
log.info("Project changed: " + project.getLocationUri());
|
||||
synchronized (listeners) {
|
||||
for (Listener listener : listeners) {
|
||||
listener.changed(project);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<IJavaProject> find(TextDocumentIdentifier doc) {
|
||||
if (mainServiceInitialized.isDone()) {
|
||||
@@ -77,30 +155,6 @@ public class JavaProjectsServiceWithFallback implements JavaProjectsService {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(Listener listener) {
|
||||
mainServiceInitialized.handle((success, failed) -> {
|
||||
if (failed!=null) {
|
||||
fallback.get().addListener(listener);
|
||||
} else {
|
||||
main.addListener(listener);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(Listener listener) {
|
||||
mainServiceInitialized.handle((success, failed) -> {
|
||||
if (failed!=null) {
|
||||
fallback.get().removeListener(listener);
|
||||
} else {
|
||||
main.removeListener(listener);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavadocProvider javadocProvider(String projectUri, CPE classpathEntry) {
|
||||
if (mainServiceInitialized.isDone()) {
|
||||
|
||||
@@ -67,6 +67,7 @@ public class JdtLsProjectCache implements InitializableJavaProjectsService {
|
||||
public void addListener(Listener listener) {
|
||||
synchronized (listeners) {
|
||||
listeners.add(listener);
|
||||
log.info("added listener - now listeners registered: " + listeners.size());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,14 +75,23 @@ public class JdtLsProjectCache implements InitializableJavaProjectsService {
|
||||
public void removeListener(Listener listener) {
|
||||
synchronized (listeners) {
|
||||
listeners.remove(listener);
|
||||
log.info("removed listener - now listeners registered: " + listeners.size());
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyCreated(JavaProject newProject) {
|
||||
logEvent("Created", newProject);
|
||||
|
||||
synchronized (listeners) {
|
||||
log.info("listeners registered: " + listeners.size());
|
||||
|
||||
for (Listener listener : listeners) {
|
||||
listener.created(newProject);
|
||||
try {
|
||||
listener.created(newProject);
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.info("listener caused exception: " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user