PT 168776173 - Integrate progress service live hovers v2

Initial integration of progress service into live hovers v2. Added new
API to make it cleared when progress for the  same taskId can be done,
and added progress reporting to SpringProcessConnectorService which can
potentially be a long running progress if several retries on refresh are
required.
This commit is contained in:
nsingh@pivotal.io
2019-11-14 13:56:02 -08:00
parent bf5b9f5a31
commit 9969c59e95
6 changed files with 58 additions and 15 deletions

View File

@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2016-2017 Pivotal, Inc.
* Copyright (c) 2016-2019 Pivotal, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -11,9 +11,21 @@
package org.springframework.ide.vscode.commons.languageserver;
@FunctionalInterface
public interface ProgressService {
public static ProgressService NO_PROGRESS = new ProgressService() {
@Override
public void progressEvent(String taskId, String statusMsg) {
}
@Override
public void progressDone(String taskId) {
}
};
/**
* Sends a progress event to the LSP client. A taskId is an arbirary id
* that can be chosen by the caller. The purpose of the id is to be a 'unique'
@@ -31,5 +43,7 @@ public interface ProgressService {
* @param statusMsg
*/
void progressEvent(String taskId, String statusMsg);
void progressDone(String taskId);
}

View File

@@ -32,7 +32,6 @@ import org.eclipse.lsp4j.ApplyWorkspaceEditParams;
import org.eclipse.lsp4j.ApplyWorkspaceEditResponse;
import org.eclipse.lsp4j.ClientCapabilities;
import org.eclipse.lsp4j.CodeLensOptions;
import org.eclipse.lsp4j.CompletionOptions;
import org.eclipse.lsp4j.Diagnostic;
import org.eclipse.lsp4j.DiagnosticSeverity;
import org.eclipse.lsp4j.ExecuteCommandOptions;
@@ -84,7 +83,6 @@ import org.springframework.ide.vscode.commons.util.CollectionUtil;
import org.springframework.ide.vscode.commons.util.text.TextDocument;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableList.Builder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
@@ -118,10 +116,19 @@ public final class SimpleLanguageServer implements Sts4LanguageServer, LanguageC
private STS4LanguageClient client;
private final LanguageServerProperties props;
private ProgressService progressService = (String taskId, String statusMsg) -> {
STS4LanguageClient client = SimpleLanguageServer.this.client;
if (client!=null) {
client.progress(new ProgressParams(taskId, statusMsg));
private ProgressService progressService = new ProgressService() {
@Override
public void progressEvent(String taskId, String statusMsg) {
STS4LanguageClient client = SimpleLanguageServer.this.client;
if (client!=null) {
client.progress(new ProgressParams(taskId, statusMsg));
}
}
@Override
public void progressDone(String taskId) {
progressEvent(taskId, null);
}
};

View File

@@ -152,7 +152,7 @@ public class BootJavaLanguageServerComponents implements LanguageServerComponent
//
// central live data components (to coordinate live data flow)
liveDataService = new SpringProcessConnectorService(liveDataProvider);
liveDataService = new SpringProcessConnectorService(server.getProgressService(), liveDataProvider);
// connect the live data provider with the hovers (for data extraction and live updates)
hoverProvider = createHoverHandler(projectFinder, sourceLinks, liveDataProvider);

View File

@@ -17,6 +17,7 @@ import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ide.vscode.commons.languageserver.ProgressService;
/**
* @author Martin Lippert
@@ -35,12 +36,15 @@ public class SpringProcessConnectorService {
private final ConcurrentMap<String, Boolean> connectedSuccess;
private final SpringProcessConnectionChangeListener connectorListener;
private final ProgressService progressService;
public SpringProcessConnectorService(SpringProcessLiveDataProvider liveDataProvider) {
public SpringProcessConnectorService(ProgressService progressService, SpringProcessLiveDataProvider liveDataProvider) {
this.liveDataProvider = liveDataProvider;
this.scheduler = new ScheduledThreadPoolExecutor(10);
this.connectors = new ConcurrentHashMap<>();
this.connectedSuccess = new ConcurrentHashMap<>();
this.progressService = progressService;
this.connectorListener = new SpringProcessConnectionChangeListener() {
@Override
@@ -140,11 +144,15 @@ public class SpringProcessConnectorService {
}
private void scheduleRefresh(String processKey, SpringProcessConnector connector, long delay, TimeUnit unit, int retryNo) {
log.info("schedule task to refresh data from process: " + processKey + " - retry no: " + retryNo);
String progressMessage = "Refreshing data from Spring process: " + processKey + " - retry no: " + retryNo;
log.info(progressMessage);
this.scheduler.schedule(() -> {
String progressId = "uniqueId";
try {
progress(progressId, progressMessage);
SpringProcessLiveData newLiveData = connector.refresh();
if (newLiveData != null) {
if (!this.liveDataProvider.add(processKey, newLiveData)) {
this.liveDataProvider.update(processKey, newLiveData);
@@ -152,18 +160,33 @@ public class SpringProcessConnectorService {
this.connectedSuccess.put(processKey, true);
}
progressDone(progressId);
}
catch (Exception e) {
log.info("problem occured during process live data refresh", e);
if (retryNo < RETRY_MAX_NO) {
scheduleRefresh(processKey, connector, RETRY_DELAY_IN_SECONDS, TimeUnit.SECONDS, retryNo + 1);
}
else {
progressDone(progressId);
disconnectProcess(processKey);
}
}
}, delay, unit);
}
private void progress(String taskId, String message) {
if (this.progressService != null) {
this.progressService.progressEvent(taskId, message);
}
}
private void progressDone(String taskId) {
if (this.progressService != null) {
this.progressService.progressDone(taskId);
}
}
}

View File

@@ -19,7 +19,6 @@ import org.springframework.ide.vscode.commons.languageserver.ProgressService;
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
import org.springframework.ide.vscode.commons.languageserver.java.ProjectObserver;
import org.springframework.ide.vscode.commons.util.FileObserver;
import org.springframework.ide.vscode.commons.util.FuzzyMap;
import org.springframework.ide.vscode.commons.util.text.IDocument;
public class DefaultSpringPropertyIndexProvider implements SpringPropertyIndexProvider {
@@ -29,7 +28,7 @@ public class DefaultSpringPropertyIndexProvider implements SpringPropertyIndexPr
private Runnable changeHandler = null;
private ProgressService progressService = (id, msg) -> { /*ignore*/ };
private ProgressService progressService = ProgressService.NO_PROGRESS;
public DefaultSpringPropertyIndexProvider(JavaProjectFinder javaProjectFinder, ProjectObserver projectObserver, FileObserver fileObserver, ValueProviderRegistry valueProviders) {
this.javaProjectFinder = javaProjectFinder;

View File

@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2016, 2017 Pivotal, Inc.
* Copyright (c) 2016, 2019 Pivotal, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -31,7 +31,7 @@ public class PropertiesIndexTest {
private static final String CUSTOM_PROPERTIES_PROJECT = "custom-properties-boot-project";
private ProjectsHarness projects = ProjectsHarness.INSTANCE;
private ProgressService progressService = (id, msg) -> { /*ignore*/ };
private ProgressService progressService = ProgressService.NO_PROGRESS;
@Test
public void springStandardPropertyPresent_Maven() throws Exception {