added more advanced caching strategy for calculating live hovers after live hover hints already got created

This commit is contained in:
Martin Lippert
2018-08-23 09:57:23 +02:00
parent 88e8e65b45
commit bff10fa51a
5 changed files with 112 additions and 28 deletions

View File

@@ -11,6 +11,7 @@
package org.springframework.ide.vscode.boot.java.handlers;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Optional;
@@ -58,14 +59,15 @@ public class BootJavaHoverProvider implements HoverHandler {
private JavaProjectFinder projectFinder;
private BootJavaLanguageServerComponents server;
private AnnotationHierarchyAwareLookup<HoverProvider> hoverProviders;
private RunningAppProvider runningAppProvider;
private Collection<SpringBootApp> runningSpringBootApps;
public BootJavaHoverProvider(BootJavaLanguageServerComponents server, JavaProjectFinder projectFinder,
AnnotationHierarchyAwareLookup<HoverProvider> specificProviders, RunningAppProvider runningAppProvider) {
this.server = server;
this.projectFinder = projectFinder;
this.hoverProviders = specificProviders;
this.runningAppProvider = runningAppProvider;
this.runningSpringBootApps = Collections.emptyList();
}
@Override
@@ -262,10 +264,11 @@ public class BootJavaHoverProvider implements HoverHandler {
private Hover provideHoverForMethodDeclaration(MethodDeclaration methodDeclaration, int offset, TextDocument doc,
IJavaProject project) {
SpringBootApp[] runningApps = getRunningSpringApps(project);
if (runningApps.length > 0) {
for (HoverProvider provider : this.hoverProviders.getAll()) {
Hover hover = provider.provideHover(methodDeclaration, offset, doc, project, runningApps);
if (hover!=null) {
if (hover != null) {
//TODO: compose multiple hovers somehow instead of just returning the first one?
return hover;
}
@@ -278,8 +281,10 @@ public class BootJavaHoverProvider implements HoverHandler {
ITypeBinding type = annotation.resolveTypeBinding();
if (type != null) {
logger.debug("Hover requested for "+type.getName());
SpringBootApp[] runningApps = getRunningSpringApps(project);
if (runningApps.length > 0) {
for (HoverProvider provider : this.hoverProviders.get(type)) {
Hover hover = provider.provideHover(exactNode, annotation, type, offset, doc, project, runningApps);
if (hover!=null) {
@@ -347,11 +352,18 @@ public class BootJavaHoverProvider implements HoverHandler {
private SpringBootApp[] getRunningSpringApps(IJavaProject project) {
try {
return RunningAppMatcher.getAllMatchingApps(runningAppProvider.getAllRunningSpringApps(), project).toArray(new SpringBootApp[0]);
Collection<SpringBootApp> allApps = this.runningSpringBootApps;
Collection<SpringBootApp> allMatchingApps = RunningAppMatcher.getAllMatchingApps(allApps, project);
return allMatchingApps.toArray(new SpringBootApp[0]);
} catch (Exception e) {
logger.error("error getting all matching projects for project'" + project.getElementName() + "'", e);
return new SpringBootApp[0];
}
}
public void setRunningSpringApps(Collection<SpringBootApp> allRunningSpringBootApps) {
this.runningSpringBootApps = allRunningSpringBootApps;
}
}

View File

@@ -17,6 +17,7 @@ import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.eclipse.lsp4j.CodeLens;
@@ -33,8 +34,12 @@ import org.springframework.ide.vscode.commons.languageserver.HighlightParams;
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
import org.springframework.ide.vscode.commons.languageserver.java.ProjectObserver;
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
import org.springframework.ide.vscode.commons.util.MemoizingProxy;
import org.springframework.ide.vscode.commons.util.text.TextDocument;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
/**
* @author Martin Lippert
*/
@@ -155,6 +160,26 @@ public class SpringLiveHoverWatchdog {
}
}
protected void update() {
if (this.watchedDocs.size() > 0) {
try {
Collection<SpringBootApp> runningBootApps = runningAppProvider.getAllRunningSpringApps();
Collection<SpringBootApp> cachedApps = createAppCaches(runningBootApps);
for (String docURI : watchedDocs) {
IJavaProject project = identifyProject(docURI);
SpringBootApp[] matchingApps = RunningAppMatcher.getAllMatchingApps(cachedApps, project).toArray(new SpringBootApp[0]);
update(docURI, matchingApps);
}
this.hoverProvider.setRunningSpringApps(cachedApps);
} catch (Exception e) {
logger.error("", e);
}
}
}
protected void update(String docURI, SpringBootApp[] runningBootApps) {
if (highlightsEnabled) {
try {
@@ -175,20 +200,20 @@ public class SpringLiveHoverWatchdog {
}
}
protected void update() {
if (this.watchedDocs.size() > 0) {
try {
Collection<SpringBootApp> runningBootApps = runningAppProvider.getAllRunningSpringApps();
private Collection<SpringBootApp> createAppCaches(Collection<SpringBootApp> runningBootApps) {
return runningBootApps.stream().map(app -> {
MethodInterceptor handler = new MemoizingProxy.MemoizingProxyHandler(app, Duration.ofMillis(20000));
SpringBootApp proxied = (SpringBootApp) Enhancer.create(SpringBootApp.class, handler);
for (String docURI : watchedDocs) {
IJavaProject project = identifyProject(docURI);
SpringBootApp[] matchingApps = RunningAppMatcher.getAllMatchingApps(runningBootApps, project).toArray(new SpringBootApp[0]);
update(docURI, matchingApps);
}
} catch (Exception e) {
logger.error("", e);
}
}
try {
proxied.getProcessName();
proxied.getProcessID();
}
catch (Exception e) {
}
return proxied;
}).filter(app -> app != null).collect(Collectors.toList());
}
private IJavaProject identifyProject(String docURI) {