summaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
authorLeif Åstrand <leif@vaadin.com>2013-04-10 10:21:59 +0300
committerLeif Åstrand <leif@vaadin.com>2013-04-10 10:21:59 +0300
commit6f593d5847389edfc9dbb7bb65114dc4be6066ae (patch)
treeeddba731c09501db053433444b04ea97ad7ea905 /client
parent48208188a5da6b143b83aa26f908e7f91163ca18 (diff)
downloadvaadin-framework-6f593d5847389edfc9dbb7bb65114dc4be6066ae.tar.gz
vaadin-framework-6f593d5847389edfc9dbb7bb65114dc4be6066ae.zip
Don't process push messages until init JSON is processed (#11529)
* The test is not running reliably in all browsers, but assuming this is a symptom of other push issues and not related to this particular bug. Change-Id: I848b57502aa01467b0f60624cf599247ec76f32f
Diffstat (limited to 'client')
-rw-r--r--client/src/com/vaadin/client/ApplicationConnection.java65
1 files changed, 60 insertions, 5 deletions
diff --git a/client/src/com/vaadin/client/ApplicationConnection.java b/client/src/com/vaadin/client/ApplicationConnection.java
index 0341a9d5c4..2fa82c6004 100644
--- a/client/src/com/vaadin/client/ApplicationConnection.java
+++ b/client/src/com/vaadin/client/ApplicationConnection.java
@@ -183,6 +183,19 @@ public class ApplicationConnection {
protected boolean applicationRunning = false;
+ /**
+ * Keep track of whether the initialization JSON has been handled. We should
+ * not process any push messages until the initial JSON has been processed.
+ */
+ private boolean initJsonHandled = false;
+
+ /**
+ * Keep track of any push messages that arrive before
+ * {@link #initJsonHandled} is set to true.
+ */
+ private JsArrayString incommingPushMessageQueue = JsArrayString
+ .createArray().cast();
+
private boolean hasActiveRequest = false;
/**
@@ -1114,6 +1127,26 @@ public class ApplicationConnection {
checkForPendingVariableBursts();
runPostRequestHooks(configuration.getRootPanelId());
}
+
+ if (!initJsonHandled) {
+ /*
+ * Assume that the first request that is fully handled is the one
+ * with the initialization data.
+ */
+ initJsonHandled = true;
+
+ int queueLength = incommingPushMessageQueue.length();
+ if (queueLength > 0) {
+ VConsole.log("Init handled, processing " + queueLength
+ + " enqueued messages");
+ for (int i = 0; i < queueLength; i++) {
+ handlePushMessage(incommingPushMessageQueue.get(i));
+ }
+ incommingPushMessageQueue.setLength(0);
+ }
+
+ }
+
// deferring to avoid flickering
Scheduler.get().scheduleDeferred(new Command() {
@Override
@@ -1258,6 +1291,14 @@ public class ApplicationConnection {
return;
}
+ /*
+ * Lock response handling to avoid a situation where something pushed
+ * from the server gets processed while waiting for e.g. lazily loaded
+ * connectors that are needed for processing the current message.
+ */
+ final Object lock = new Object();
+ suspendReponseHandling(lock);
+
VConsole.log("Handling message from server");
eventBus.fireEvent(new ResponseHandlingStartedEvent(this));
@@ -1476,6 +1517,7 @@ public class ApplicationConnection {
// not sent asynchronously
endRequest();
}
+ resumeResponseHandling(lock);
if (Profiler.isEnabled()) {
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
@@ -3264,11 +3306,19 @@ public class ApplicationConnection {
* suspended.
*/
private void handlePendingMessages() {
- for (PendingUIDLMessage pending : pendingUIDLMessages) {
- handleUIDLMessage(pending.getStart(), pending.getJsonText(),
- pending.getJson());
+ if (!pendingUIDLMessages.isEmpty()) {
+ /*
+ * Clear the list before processing enqueued messages to support
+ * reentrancy
+ */
+ List<PendingUIDLMessage> pendingMessages = pendingUIDLMessages;
+ pendingUIDLMessages = new ArrayList<PendingUIDLMessage>();
+
+ for (PendingUIDLMessage pending : pendingMessages) {
+ handleReceivedJSONMessage(pending.getStart(),
+ pending.getJsonText(), pending.getJson());
+ }
}
- pendingUIDLMessages.clear();
}
private boolean handleErrorInDelegate(String details, int statusCode) {
@@ -3348,6 +3398,11 @@ public class ApplicationConnection {
}
public void handlePushMessage(String message) {
- handleJSONText(message, 200);
+ if (initJsonHandled) {
+ handleJSONText(message, 200);
+ } else {
+ VConsole.log("Enqueuing push message has init has not yet been handled");
+ incommingPushMessageQueue.push(message);
+ }
}
}