]> source.dussan.org Git - vaadin-framework.git/commitdiff
Make dirty connector handling more deterministic (#9396)
authorHenri Sara <henri.sara@gmail.com>
Fri, 26 May 2017 05:48:40 +0000 (08:48 +0300)
committerPekka Hyvönen <pekka@vaadin.com>
Fri, 26 May 2017 05:48:40 +0000 (08:48 +0300)
Changes in connector tracking and cleaning (#9305) changed the
behavior so that the framework runs beforeClientResponse methods in
a non-deterministic and possibly different order than before.

This change makes the framework call beforeClientResponse methods in
a more deterministic order (parents before children) and checks that
the connector tracker knows the connector.

server/src/main/java/com/vaadin/server/communication/UidlWriter.java

index c6c2d77fcb19888f8387bca0bc052e3cf20ece6c..d27fc3f0aea51d06f1b8f306461d064e91bdc55d 100644 (file)
@@ -90,10 +90,9 @@ public class UidlWriter implements Serializable {
 
         while (true) {
             ArrayList<ClientConnector> connectorsToProcess = new ArrayList<>();
-            for (ClientConnector c : uiConnectorTracker.getDirtyConnectors()) {
-                if (!processedConnectors.contains(c)
-                        && LegacyCommunicationManager
-                                .isConnectorVisibleToClient(c)) {
+            for (ClientConnector c : uiConnectorTracker
+                    .getDirtyVisibleConnectors()) {
+                if (!processedConnectors.contains(c)) {
                     connectorsToProcess.add(c);
                 }
             }
@@ -102,9 +101,25 @@ public class UidlWriter implements Serializable {
                 break;
             }
 
+            // process parents before children
+            Collections.sort(connectorsToProcess,
+                    Comparator.comparingInt(conn -> {
+                        int depth = 0;
+                        ClientConnector connector = conn;
+                        // this is a very fast operation, even for 100+ levels
+                        while (connector.getParent() != null) {
+                            ++depth;
+                            connector = connector.getParent();
+                        }
+                        return depth;
+                    }));
+
             for (ClientConnector connector : connectorsToProcess) {
-                boolean initialized = uiConnectorTracker
-                        .isClientSideInitialized(connector);
+                // call isDirty() to find out if ConnectorTracker knows the
+                // connector
+                boolean initialized = uiConnectorTracker.isDirty(connector)
+                        && uiConnectorTracker
+                                .isClientSideInitialized(connector);
                 processedConnectors.add(connector);
 
                 try {