Try to make workspace symbol provider more 'reactive'

This commit is contained in:
Kris De Volder
2017-11-03 17:42:47 -07:00
parent c69a1c7b16
commit cb7f0267f9
4 changed files with 48 additions and 38 deletions

View File

@@ -16,7 +16,9 @@ Require-Bundle: org.eclipse.ui,
com.google.guava,
org.eclipse.core.jobs,
org.eclipse.core.runtime;bundle-version="3.13.0",
org.springsource.ide.eclipse.commons.core;bundle-version="3.9.1"
org.springsource.ide.eclipse.commons.core;bundle-version="3.9.1",
io.projectreactor.reactor-core;bundle-version="3.0.7",
org.reactivestreams.reactive-streams;bundle-version="1.0.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-Activator: org.springframework.tooling.ls.eclipse.gotosymbol.GotoSymbolPlugin
Bundle-ActivationPolicy: lazy

View File

@@ -13,7 +13,7 @@ package org.springframework.tooling.ls.eclipse.gotosymbol.dialogs;
import java.time.Duration;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.resources.IProject;
@@ -31,10 +31,14 @@ import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil;
import com.google.common.collect.ImmutableList;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@SuppressWarnings("restriction")
public class InWorkspaceSymbolsProvider implements SymbolsProvider {
private static final Duration TIMEOUT = Duration.ofSeconds(2);
private static final int MAX_RESULTS = 200;
private List<LanguageServer> languageServers;
@@ -58,19 +62,22 @@ public class InWorkspaceSymbolsProvider implements SymbolsProvider {
// - producing results per server so don't have to wait for one slow server to see the rest.
//However it will also add complexity to the code that consumes this and at this time we only
// really use this with a single language server anyways.
WorkspaceSymbolParams params = new WorkspaceSymbolParams(query);
ImmutableList.Builder<SymbolInformation> allSymbols = ImmutableList.builder();
for (LanguageServer server : this.languageServers) {
try {
WorkspaceSymbolParams params = new WorkspaceSymbolParams(query);
List<? extends SymbolInformation> symbolsFuture =
server.getWorkspaceService().symbol(params)
.get(TIMEOUT.toMillis(), TimeUnit.MILLISECONDS);
allSymbols.addAll(symbolsFuture);
} catch (Exception e) {
GotoSymbolPlugin.getInstance().getLog().log(ExceptionUtil.status(e));
}
}
return allSymbols.build();
Flux<SymbolInformation> symbols = Flux.fromIterable(this.languageServers)
.flatMap(server -> Mono.fromFuture(server.getWorkspaceService().symbol(params))
.timeout(TIMEOUT)
.doOnError(e -> log(e))
.onErrorReturn(ImmutableList.of())
.flatMapMany(Flux::fromIterable)
);
//Consider letting the Flux go out from here instead of blocking and collecting elements.
return symbols.take(MAX_RESULTS).collect(Collectors.toList()).block();
}
private static void log(Throwable e) {
GotoSymbolPlugin.getInstance().getLog().log(ExceptionUtil.status(e));
}
public static InWorkspaceSymbolsProvider createFor(ExecutionEvent event) {

View File

@@ -65,6 +65,8 @@ public class SpringBootApp {
private static final String LOCAL_CONNECTOR_ADDRESS = "com.sun.management.jmxremote.localConnectorAddress";
private Boolean isSpringBootApp;
private final Supplier<String> jmxConnect = Suppliers.memoize(() -> {
String address = null;
try {
@@ -114,33 +116,31 @@ public class SpringBootApp {
}
public boolean isSpringBootApp() {
return !containsSystemProperty("sts4.languageserver.name")
&& (
isSpringBootAppClasspath() ||
isSpringBootAppSysprops()
);
if (isSpringBootApp==null) {
try {
isSpringBootApp = !containsSystemProperty("sts4.languageserver.name")
&& (
isSpringBootAppClasspath() ||
isSpringBootAppSysprops()
);
} catch (Exception e) {
Log.log(e);
return false;
}
}
return isSpringBootApp;
}
private boolean isSpringBootAppSysprops() {
try {
Properties sysprops = this.vm.getSystemProperties();
return "org.springframework.boot.loader".equals(sysprops.getProperty("java.protocol.handler.pkgs"));
} catch (Exception e) {
Log.log(e);
}
return false;
private boolean isSpringBootAppSysprops() throws IOException {
Properties sysprops = this.vm.getSystemProperties();
return "org.springframework.boot.loader".equals(sysprops.getProperty("java.protocol.handler.pkgs"));
}
private boolean isSpringBootAppClasspath() {
try {
Properties props = this.vm.getSystemProperties();
String classpath = (String) props.get("java.class.path");
String[] cpElements = getClasspath(classpath);
return contains(cpElements, "spring-boot");
} catch (Exception e) {
Log.log(e);
}
return false;
private boolean isSpringBootAppClasspath() throws IOException {
Properties props = this.vm.getSystemProperties();
String classpath = (String) props.get("java.class.path");
String[] cpElements = getClasspath(classpath);
return contains(cpElements, "spring-boot");
}

View File

@@ -50,7 +50,8 @@ public class SimpleWorkspaceService implements WorkspaceService {
}
return Mono.fromCallable(() -> {
server.waitForReconcile();
return workspaceSymbolHandler.handle(params);
List<? extends SymbolInformation> symbols = workspaceSymbolHandler.handle(params);
return symbols==null ? ImmutableList.of() : symbols;
})
.toFuture()
.thenApply(l -> (List<? extends SymbolInformation>)l);