summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Ahlroos <john@vaadin.com>2013-10-28 16:41:24 +0200
committerVaadin Code Review <review@vaadin.com>2013-10-30 07:37:48 +0000
commit12656003e98566b0d551f4460f08cc62353fd540 (patch)
treec5b557eb85fa102fbde3a13129e9e05160eef94e
parent8971651a93920c7b75316f0c3794682afebcddac (diff)
downloadvaadin-framework-12656003e98566b0d551f4460f08cc62353fd540.tar.gz
vaadin-framework-12656003e98566b0d551f4460f08cc62353fd540.zip
Stop polling if Communication Error #12362
This change adds a new ApplicationStopped event which is triggered whenever the ApplicationConnection marks the application as stopped. This event is listened by the UIConnector and will terminate any polling that might be currently done. Change-Id: I5e698fba7a94f530f69a9f6f554eea896c370824
-rw-r--r--client/src/com/vaadin/client/ApplicationConnection.java89
-rw-r--r--client/src/com/vaadin/client/ui/ui/UIConnector.java25
2 files changed, 105 insertions, 9 deletions
diff --git a/client/src/com/vaadin/client/ApplicationConnection.java b/client/src/com/vaadin/client/ApplicationConnection.java
index 4314602bc2..f95cec4fbc 100644
--- a/client/src/com/vaadin/client/ApplicationConnection.java
+++ b/client/src/com/vaadin/client/ApplicationConnection.java
@@ -26,6 +26,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.logging.Logger;
import com.google.gwt.aria.client.LiveValue;
import com.google.gwt.aria.client.RelevantValue;
@@ -63,6 +64,7 @@ import com.google.gwt.user.client.Window.ClosingHandler;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.ApplicationConfiguration.ErrorMessage;
+import com.vaadin.client.ApplicationConnection.ApplicationStoppedEvent;
import com.vaadin.client.ResourceLoader.ResourceLoadEvent;
import com.vaadin.client.ResourceLoader.ResourceLoadListener;
import com.vaadin.client.communication.HasJavaScriptConnectorHelper;
@@ -294,7 +296,7 @@ public class ApplicationConnection {
}
@Override
- public com.google.gwt.event.shared.GwtEvent.Type<CommunicationHandler> getAssociatedType() {
+ public Type<CommunicationHandler> getAssociatedType() {
return TYPE;
}
@@ -314,7 +316,7 @@ public class ApplicationConnection {
}
@Override
- public com.google.gwt.event.shared.GwtEvent.Type<CommunicationHandler> getAssociatedType() {
+ public Type<CommunicationHandler> getAssociatedType() {
return TYPE;
}
@@ -349,7 +351,7 @@ public class ApplicationConnection {
public static Type<CommunicationHandler> TYPE = new Type<CommunicationHandler>();
@Override
- public com.google.gwt.event.shared.GwtEvent.Type<CommunicationHandler> getAssociatedType() {
+ public Type<CommunicationHandler> getAssociatedType() {
return TYPE;
}
@@ -360,6 +362,34 @@ public class ApplicationConnection {
}
/**
+ * Event triggered when a application is stopped by calling
+ * {@link ApplicationConnection#setApplicationRunning(false)}.
+ *
+ * To listen for the event add a {@link ApplicationStoppedHandler} by
+ * invoking
+ * {@link ApplicationConnection#addHandler(ApplicationStoppedEvent.Type, ApplicationStoppedHandler)}
+ * to the {@link ApplicationConnection}
+ *
+ * @since 7.1.8
+ * @author Vaadin Ltd
+ */
+ public static class ApplicationStoppedEvent extends
+ GwtEvent<ApplicationStoppedHandler> {
+
+ public static Type<ApplicationStoppedHandler> TYPE = new Type<ApplicationStoppedHandler>();
+
+ @Override
+ public Type<ApplicationStoppedHandler> getAssociatedType() {
+ return TYPE;
+ }
+
+ @Override
+ protected void dispatch(ApplicationStoppedHandler listener) {
+ listener.onApplicationStopped(this);
+ }
+ }
+
+ /**
* Allows custom handling of communication errors.
*/
public interface CommunicationErrorHandler {
@@ -377,6 +407,27 @@ public class ApplicationConnection {
public boolean onError(String details, int statusCode);
}
+ /**
+ * A listener for listening to application stopped events. The listener can
+ * be added to a {@link ApplicationConnection} by invoking
+ * {@link ApplicationConnection#addHandler(ApplicationStoppedEvent.Type, ApplicationStoppedHandler)}
+ *
+ * @since 7.1.8
+ * @author Vaadin Ltd
+ */
+ public interface ApplicationStoppedHandler extends EventHandler {
+
+ /**
+ * Triggered when the {@link ApplicationConnection} marks a previously
+ * running application as stopped by invoking
+ * {@link ApplicationConnection#setApplicationRunning(false)}
+ *
+ * @param event
+ * the event triggered by the {@link ApplicationConnection}
+ */
+ void onApplicationStopped(ApplicationStoppedEvent event);
+ }
+
private CommunicationErrorHandler communicationErrorDelegate = null;
private VLoadingIndicator loadingIndicator;
@@ -751,6 +802,10 @@ public class ApplicationConnection {
showCommunicationError(details, statusCode);
}
endRequest();
+
+ // Consider application not running any more and prevent all
+ // future requests
+ setApplicationRunning(false);
}
@Override
@@ -882,10 +937,10 @@ public class ApplicationConnection {
VConsole.log("JSON parsing took "
+ (new Date().getTime() - start.getTime()) + "ms");
- if (applicationRunning) {
+ if (isApplicationRunning()) {
handleReceivedJSONMessage(start, jsonText, json);
} else {
- applicationRunning = true;
+ setApplicationRunning(true);
handleWhenCSSLoaded(jsonText, json);
}
}
@@ -1121,7 +1176,7 @@ public class ApplicationConnection {
retryCanceledActiveRequest = false;
webkitMaybeIgnoringRequests = false;
- if (applicationRunning) {
+ if (isApplicationRunning()) {
checkForPendingVariableBursts();
runPostRequestHooks(configuration.getRootPanelId());
}
@@ -1456,7 +1511,7 @@ public class ApplicationConnection {
error.getString("message"),
error.getString("url"));
- applicationRunning = false;
+ setApplicationRunning(false);
}
Profiler.leave("Error handling");
}
@@ -2379,6 +2434,12 @@ public class ApplicationConnection {
*/
public void addMethodInvocationToQueue(MethodInvocation invocation,
boolean delayed, boolean lastOnly) {
+ if (!isApplicationRunning()) {
+ getLogger()
+ .warning(
+ "Trying to invoke method on not yet started or stopped application");
+ return;
+ }
String tag;
if (lastOnly) {
tag = invocation.getLastOnlyTag();
@@ -2437,7 +2498,7 @@ public class ApplicationConnection {
private boolean deferedSendPending = false;
private void doSendPendingVariableChanges() {
- if (applicationRunning) {
+ if (isApplicationRunning()) {
if (hasActiveRequest() || (push != null && !push.isActive())) {
// skip empty queues if there are pending bursts to be sent
if (pendingInvocations.size() > 0 || pendingBursts.size() == 0) {
@@ -2449,6 +2510,11 @@ public class ApplicationConnection {
} else {
buildAndSendVariableBurst(pendingInvocations);
}
+ } else {
+ getLogger()
+ .warning(
+ "Trying to send variable changes from not yet started or stopped application");
+ return;
}
}
@@ -3384,6 +3450,9 @@ public class ApplicationConnection {
}
public void setApplicationRunning(boolean running) {
+ if (applicationRunning && !running) {
+ eventBus.fireEvent(new ApplicationStoppedEvent());
+ }
applicationRunning = running;
}
@@ -3486,4 +3555,8 @@ public class ApplicationConnection {
}
}
+ private static Logger getLogger() {
+ return Logger.getLogger(ApplicationConnection.class.getName());
+ }
+
}
diff --git a/client/src/com/vaadin/client/ui/ui/UIConnector.java b/client/src/com/vaadin/client/ui/ui/UIConnector.java
index 46b5f63180..8813d70609 100644
--- a/client/src/com/vaadin/client/ui/ui/UIConnector.java
+++ b/client/src/com/vaadin/client/ui/ui/UIConnector.java
@@ -45,6 +45,7 @@ import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.web.bindery.event.shared.HandlerRegistration;
import com.vaadin.client.ApplicationConnection;
+import com.vaadin.client.ApplicationConnection.ApplicationStoppedEvent;
import com.vaadin.client.BrowserInfo;
import com.vaadin.client.ComponentConnector;
import com.vaadin.client.ConnectorHierarchyChangeEvent;
@@ -320,7 +321,8 @@ public class UIConnector extends AbstractSingleComponentContainerConnector
.getPaintableAttribute("focused", getConnection());
if (paintable == null) {
- // Do not try to focus invisible components which not present in UIDL
+ // Do not try to focus invisible components which not
+ // present in UIDL
return;
}
@@ -467,6 +469,21 @@ public class UIConnector extends AbstractSingleComponentContainerConnector
// side-effects from focusing (scrollIntoView).
getWidget().getElement().focus();
}
+
+ applicationConnection.addHandler(
+ ApplicationConnection.ApplicationStoppedEvent.TYPE,
+ new ApplicationConnection.ApplicationStoppedHandler() {
+
+ @Override
+ public void onApplicationStopped(
+ ApplicationStoppedEvent event) {
+ // Stop any polling
+ if (pollTimer != null) {
+ pollTimer.cancel();
+ pollTimer = null;
+ }
+ }
+ });
}
private ClickEventHandler clickEventHandler = new ClickEventHandler(this) {
@@ -686,6 +703,12 @@ public class UIConnector extends AbstractSingleComponentContainerConnector
pollTimer = new Timer() {
@Override
public void run() {
+ if (getState().pollInterval < 0) {
+ // Polling has been cancelled server side
+ pollTimer.cancel();
+ pollTimer = null;
+ return;
+ }
getRpcProxy(UIServerRpc.class).poll();
// Send changes even though poll is @Delayed
getConnection().sendPendingVariableChanges();