diff options
author | Leif Åstrand <leif@vaadin.com> | 2013-04-10 10:21:59 +0300 |
---|---|---|
committer | Leif Åstrand <leif@vaadin.com> | 2013-04-10 10:21:59 +0300 |
commit | 6f593d5847389edfc9dbb7bb65114dc4be6066ae (patch) | |
tree | eddba731c09501db053433444b04ea97ad7ea905 /client | |
parent | 48208188a5da6b143b83aa26f908e7f91163ca18 (diff) | |
download | vaadin-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.java | 65 |
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); + } } } |