Add timeout to unblock VirtualMachine.getSystemProperties

This commit is contained in:
Kris De Volder
2018-09-19 15:16:59 -07:00
parent ba9c88b930
commit 5b967ccd37
6 changed files with 38 additions and 11 deletions

View File

@@ -11,18 +11,25 @@
package org.springframework.ide.vscode.commons.boot.app.cli;
import java.io.IOException;
import java.time.Duration;
import java.util.Collection;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ide.vscode.commons.util.AsyncRunner;
import org.springframework.ide.vscode.commons.util.CollectorUtil;
import org.springframework.ide.vscode.commons.util.ExceptionUtil;
import com.sun.tools.attach.AttachNotSupportedException;
import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.VirtualMachineDescriptor;
import reactor.core.scheduler.Schedulers;
/**
* @author Martin Lippert
*/
@@ -30,11 +37,18 @@ public class LocalSpringBootApp extends AbstractSpringBootApp {
private static final Logger logger = LoggerFactory.getLogger(LocalSpringBootApp.class);
private static AsyncRunner async = new AsyncRunner(Schedulers.elastic());
private static <T> T withTimeout(Callable<T> doit) throws Exception {
return async.invoke(TIMEOUT, doit).get();
}
private VirtualMachine vm;
private VirtualMachineDescriptor vmd;
private static final String LOCAL_CONNECTOR_ADDRESS = "com.sun.management.jmxremote.localConnectorAddress";
private static final Duration TIMEOUT = Duration.ofMillis(1000);
private Boolean isSpringBootApp;
private static LocalSpringBootAppCache cache = new LocalSpringBootAppCache();
@@ -111,7 +125,7 @@ public class LocalSpringBootApp extends AbstractSpringBootApp {
return isSpringBootApp;
}
private boolean isSpringBootAppSysprops() throws IOException {
private boolean isSpringBootAppSysprops() throws Exception {
Properties sysprops = getSystemProperties();
return "org.springframework.boot.loader".equals(sysprops.getProperty("java.protocol.handler.pkgs"));
}
@@ -121,11 +135,11 @@ public class LocalSpringBootApp extends AbstractSpringBootApp {
}
@Override
public Properties getSystemProperties() throws IOException {
return this.vm.getSystemProperties();
public Properties getSystemProperties() throws Exception {
return withTimeout(() -> vm.getSystemProperties());
}
public boolean containsSystemProperty(Object key) throws IOException {
public boolean containsSystemProperty(Object key) throws Exception {
Properties props = getSystemProperties();
return props.containsKey(key);
}

View File

@@ -21,8 +21,8 @@ import org.eclipse.lsp4j.Unregistration;
import org.eclipse.lsp4j.UnregistrationParams;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ide.vscode.commons.languageserver.util.AsyncRunner;
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
import org.springframework.ide.vscode.commons.util.AsyncRunner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;

View File

@@ -10,7 +10,7 @@
*******************************************************************************/
package org.springframework.ide.vscode.commons.languageserver.util;
import static org.springframework.ide.vscode.commons.languageserver.util.AsyncRunner.thenLog;
import static org.springframework.ide.vscode.commons.util.AsyncRunner.thenLog;
import java.net.URI;
import java.nio.file.Paths;
@@ -74,6 +74,7 @@ import org.springframework.ide.vscode.commons.languageserver.reconcile.IReconcil
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemSeverity;
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblem;
import org.springframework.ide.vscode.commons.util.Assert;
import org.springframework.ide.vscode.commons.util.AsyncRunner;
import org.springframework.ide.vscode.commons.util.BadLocationException;
import org.springframework.ide.vscode.commons.util.CollectionUtil;
import org.springframework.ide.vscode.commons.util.Log;
@@ -143,7 +144,7 @@ public class SimpleLanguageServer implements Sts4LanguageServer, LanguageClientA
private Map<String, ExecuteCommandHandler> commands = new HashMap<>();
private AsyncRunner async = new AsyncRunner();
private AsyncRunner async = new AsyncRunner(Schedulers.newSingle("SimpleLanguaserver main thread"));
private ClasspathListenerManager classpathListenerManager;
@Override

View File

@@ -56,6 +56,7 @@ import org.eclipse.lsp4j.services.LanguageClient;
import org.eclipse.lsp4j.services.TextDocumentService;
import org.springframework.ide.vscode.commons.languageserver.quickfix.Quickfix;
import org.springframework.ide.vscode.commons.util.Assert;
import org.springframework.ide.vscode.commons.util.AsyncRunner;
import org.springframework.ide.vscode.commons.util.BadLocationException;
import org.springframework.ide.vscode.commons.util.CollectorUtil;
import org.springframework.ide.vscode.commons.util.ExceptionUtil;

View File

@@ -29,6 +29,7 @@ import org.eclipse.lsp4j.services.WorkspaceService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ide.vscode.commons.util.Assert;
import org.springframework.ide.vscode.commons.util.AsyncRunner;
import org.springframework.ide.vscode.commons.util.FileObserver;
import org.springframework.ide.vscode.commons.util.Log;

View File

@@ -8,13 +8,13 @@
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.commons.languageserver.util;
package org.springframework.ide.vscode.commons.util;
import java.time.Duration;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import org.slf4j.Logger;
import org.springframework.ide.vscode.commons.util.RunnableWithException;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Scheduler;
@@ -22,14 +22,24 @@ import reactor.core.scheduler.Schedulers;
public class AsyncRunner {
private static Scheduler executor = Schedulers.newSingle("STS4 Thread");
private Scheduler executor;
// Used in test harness to wait for all pending request to finish.
// We only need to remember the last request as requests are executed in order, so if
// the last request is done, all requests are done
private CompletableFuture<?> lastRequest;
public AsyncRunner() {
public AsyncRunner(Scheduler scheduler) {
this.executor = scheduler;
}
public synchronized <T> CompletableFuture<T> invoke(Duration timeout, Callable<T> callable) {
CompletableFuture<T> x = Mono.fromCallable(callable)
.timeout(timeout)
.subscribeOn(executor)
.toFuture();
lastRequest = x;
return x;
}
public synchronized <T> CompletableFuture<T> invoke(Callable<T> callable) {