]> gerrit.simantics Code Review - simantics/platform.git/commitdiff
Fixes needed in components when using db threading 05/1905/1
authorAntti Villberg <antti.villberg@semantum.fi>
Tue, 10 Jul 2018 09:04:49 +0000 (12:04 +0300)
committerAntti Villberg <antti.villberg@semantum.fi>
Tue, 10 Jul 2018 09:04:49 +0000 (12:04 +0300)
gitlab #5

Change-Id: Ic5aee07ad9fa59dcebb76baaf59eb2ae06c46c31

bundles/org.simantics.browsing.ui.common/src/org/simantics/browsing/ui/common/internal/GENodeQueryManager.java
bundles/org.simantics.browsing.ui.common/src/org/simantics/browsing/ui/common/internal/IGraphExplorerContext.java
bundles/org.simantics.browsing.ui.common/src/org/simantics/browsing/ui/common/viewpoints/ViewpointStub.java
bundles/org.simantics.browsing.ui.nattable/src/org/simantics/browsing/ui/nattable/NatTableGraphExplorer.java
bundles/org.simantics.browsing.ui.swt/src/org/simantics/browsing/ui/swt/GraphExplorerImpl.java
bundles/org.simantics.browsing.ui.swt/src/org/simantics/browsing/ui/swt/GraphExplorerImpl2.java
bundles/org.simantics.browsing.ui/src/org/simantics/browsing/ui/PrimitiveQueryUpdater.java
bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/DiagramContentRequest.java
bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/GraphToDiagramSynchronizer.java

index 6921a3b2fab092a171ade1b348b65614ec5f987c..d6bba94bff8ad194f517c7adca8ce68cd3033dd4 100644 (file)
@@ -511,4 +511,8 @@ public class GENodeQueryManager implements NodeQueryManager, PrimitiveQueryUpdat
        ge.getCache().decRef(context);
     }
     
+    public void execFromQuery(Runnable runnable) {
+       ge.execFromQuery(runnable);
+    }
+    
 }
index b832f6c66e1e021fa2c7f02b00c835b7639a9a65..342153604baebea307e22a4bf52b47fb4be7f2d2 100644 (file)
@@ -60,5 +60,6 @@ public interface IGraphExplorerContext extends IDisposable {
     int getActivityInt();
 
     void scheduleQueryUpdate(Runnable r);
+    void execFromQuery(Runnable r);
 
 }
index 4895d3f75425ed00df79a8703c7656a41e52c18a..b33b57a0b720df1b5a20f5b0aefcd1c57260afb0 100644 (file)
@@ -29,10 +29,21 @@ public abstract class ViewpointStub implements Viewpoint {
     protected Boolean        hasChildren = Viewpoint.PENDING_HAS_CHILDREN;
 
     final public void setChildren(PrimitiveQueryUpdater updater, NodeContext[] children) {
+       
         if (children == null)
             throw new NullPointerException(this + ": null children produced by " + getClass().getName());
-        for(NodeContext c : children) updater.incRef(c);
-        for(NodeContext c : this.children) updater.decRef(c);
+        
+        final NodeContext[] currentChildren = this.children;
+        
+        updater.execFromQuery(new Runnable() {
+
+                       @Override
+                       public void run() {
+                       for(NodeContext c : children) updater.incRef(c);
+                       for(NodeContext c : currentChildren) updater.decRef(c);
+                       }
+               
+        });
         this.children = children;
     }
 
index 6765f65ead2e0a87877ee52c73f969b452bac0d6..a29fde4c56d58e2558d2db627259c6a9e2021fbc 100644 (file)
@@ -2384,6 +2384,11 @@ public class NatTableGraphExplorer extends GraphExplorerImplBase implements Grap
             }
         }
 
+        @Override
+        public void execFromQuery(java.lang.Runnable r) {
+               ge.queryUpdateScheduler.execute(r);        
+        }
+
         Runnable QUERY_UPDATE_SCHEDULER = new Runnable() {
             @Override
             public void run() {
index 0e45f86ca4843fe53233ecec6217a07026ee4954..37532c64f45d6c36a8fce06d5d63a4b92ccbd7f2 100644 (file)
@@ -465,6 +465,11 @@ class GraphExplorerImpl extends GraphExplorerImplBase implements Listener, Graph
                 queryUpdateScheduler.execute(QUERY_UPDATE_SCHEDULER);
             }
         }
+        
+        @Override
+        public void execFromQuery(java.lang.Runnable r) {
+               queryUpdateScheduler.execute(r);        
+        }
 
         Runnable QUERY_UPDATE_SCHEDULER = new Runnable() {
             @Override
index 928bed03facc844eea8ef2603307e0a2c988f965..c3407a4fdedfce3bce342b46a6b7ee07f08c8cfe 100644 (file)
@@ -1609,6 +1609,11 @@ public class GraphExplorerImpl2 extends GraphExplorerImplBase implements GraphEx
             }
         }
 
+        @Override
+        public void execFromQuery(java.lang.Runnable r) {
+               ge.queryUpdateScheduler.execute(r);        
+        }
+
         Runnable QUERY_UPDATE_SCHEDULER = new Runnable() {
             @Override
             public void run() {
index c10df01b0e5287be95c66e36d1bb548d28a5d97f..c48e947a808b80dc3e3a61c69eda60ba2e5003c2 100644 (file)
@@ -63,5 +63,7 @@ public interface PrimitiveQueryUpdater {
     
     void incRef(NodeContext context);
     void decRef(NodeContext context);
+    
+    void execFromQuery(Runnable runnable);
 
 }
\ No newline at end of file
index 56063b990f71e771180a75acfd06db99b09877fa..845adb4cc0d95664ec816f8986063604209734ef 100644 (file)
  *******************************************************************************/
 package org.simantics.diagram.adapter;
 
-import gnu.trove.list.array.TIntArrayList;
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.procedure.TIntProcedure;
-import gnu.trove.set.hash.THashSet;
-
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
 
-import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
+import org.simantics.db.common.GraphSemaphore;
 import org.simantics.db.common.procedure.adapter.ProcedureAdapter;
+import org.simantics.db.common.utils.OrderedSetUtils;
 import org.simantics.db.exception.DatabaseException;
-import org.simantics.db.procedure.AsyncMultiProcedure;
-import org.simantics.db.procedure.AsyncProcedure;
 import org.simantics.diagram.content.ConnectionPartData;
 import org.simantics.diagram.content.ConnectionPartRequest;
 import org.simantics.diagram.content.DiagramContents;
@@ -37,6 +32,11 @@ import org.simantics.diagram.stubs.DiagramResource;
 import org.simantics.diagram.synchronization.ErrorHandler;
 import org.simantics.g2d.canvas.ICanvasContext;
 
+import gnu.trove.list.array.TIntArrayList;
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.procedure.TIntProcedure;
+import gnu.trove.set.hash.THashSet;
+
 /**
  * @author Tuukka Lehtonen
  */
@@ -71,124 +71,149 @@ public class DiagramContentRequest extends BaseRequest<Resource, DiagramContents
         // These help loading result.elements in the correct order.
         final AtomicInteger index = new AtomicInteger();
         final TIntArrayList unrecognizedElementIndices = new TIntArrayList();
-
-        g.forOrderedSet(data, new AsyncMultiProcedure<Resource>() {
-
-            @Override
-            public void execute(AsyncReadGraph graph, final Resource component) {
-
-                // Must add the elements to the result set here in order to
-                // keep their order the same as in the ordered set.
-                final int elementIndex = index.getAndIncrement();
-                result.elements.add(component);
-
-                graph.forTypes(component, new AsyncProcedure<Set<Resource>>() {
-
-                    @Override
-                    public void exception(AsyncReadGraph graph, Throwable t) {
-                        if (errorHandler != null)
-                            errorHandler.error(t.getMessage(), t);
-                    }
-
-                    @Override
-                    public void execute(AsyncReadGraph graph, Set<Resource> types) {
-                        if (types.contains(DIA.Connection)) {
-                            if (types.contains(DIA.RouteGraphConnection)) {
-                                graph.asyncRequest(new RouteGraphConnectionPartRequest(errorHandler, DIA, component),
-                                        new ProcedureAdapter<RouteGraphConnectionPartData>() {
-                                    @Override
-                                    public void execute(RouteGraphConnectionPartData partData) {
-                                        synchronized (result) {
-                                            for (EdgeResource link : partData.links) {
-                                                result.routeLinks.add(link);
-                                                result.partToConnection.put(link, component);
-                                                result.connectionToParts.add(component, link);
-                                            }
-                                            for (Resource line : partData.routeLines) {
-                                                result.routeLines.add(line);
-                                                result.connectionToParts.add(component, line);
-                                                result.partToConnection.put(line, component);
-                                            }
-                                            for (Resource point : partData.routePoints) {
-                                                result.routePoints.add(point);
-                                                result.connectionToParts.add(component, point);
-                                                result.partToConnection.put(point, component);
-                                            }
-                                        }
-                                    }
-                                });
-
-                                synchronized (result.routeGraphConnectionSet) {
-                                    result.routeGraphConnectionSet.add(component);
-                                }
-                            } else {
-                                graph.asyncRequest(new ConnectionPartRequest(errorHandler, DIA, component),
-                                        new ProcedureAdapter<ConnectionPartData>() {
-                                    @Override
-                                    public void execute(ConnectionPartData partData) {
-                                        synchronized (result) {
-                                            for (EdgeResource er : partData.edges) {
-                                                result.connectionSegments.add(er);
-                                                result.partToConnection.put(er, component);
-                                                result.connectionToParts.add(component, er);
-                                            }
-                                            for (Resource bp : partData.branchPoints) {
-                                                result.branchPoints.add(bp);
-                                                result.connectionToParts.add(component, bp);
-                                                result.partToConnection.put(bp, component);
-                                            }
-                                        }
-                                    }
-                                });
-
-                                synchronized (result.connectionSet) {
-                                    result.connectionSet.add(component);
-                                }
-                            }
-                        }
-                        else if (types.contains(DIA.Element)) {
-                            synchronized (result.nodeSet) {
-                                result.nodeSet.add(component);
-                            }
-                        }
-                        else {
-                            synchronized (unrecognizedElementIndices) {
-                                // Unrecognized element, mark it to be
-                                // removed after everything is processed.
-                                unrecognizedElementIndices.add(elementIndex);
-                            }
-                        }
-                    }
-
-                });
-
-            }
-
+        
+        Collection<Resource> components = OrderedSetUtils.toList(g, data);
+        
+        GraphSemaphore s = new GraphSemaphore(g, 0);
+        
+        for(Resource component : components) {
+               
+            // Must add the elements to the result set here in order to
+            // keep their order the same as in the ordered set.
+            final int elementIndex = index.getAndIncrement();
+            result.elements.add(component);
+
+               Set<Resource> types = g.getTypes(component);
+               
+                if (types.contains(DIA.Connection)) {
+                 if (types.contains(DIA.RouteGraphConnection)) {
+                     g.asyncRequest(new RouteGraphConnectionPartRequest(errorHandler, DIA, component),
+                             new ProcedureAdapter<RouteGraphConnectionPartData>() {
+                         @Override
+                         public void execute(RouteGraphConnectionPartData partData) {
+                             synchronized (result) {
+                                 for (EdgeResource link : partData.links) {
+                                     result.routeLinks.add(link);
+                                     result.partToConnection.put(link, component);
+                                     result.connectionToParts.add(component, link);
+                                 }
+                                 for (Resource line : partData.routeLines) {
+                                     result.routeLines.add(line);
+                                     result.connectionToParts.add(component, line);
+                                     result.partToConnection.put(line, component);
+                                 }
+                                 for (Resource point : partData.routePoints) {
+                                     result.routePoints.add(point);
+                                     result.connectionToParts.add(component, point);
+                                     result.partToConnection.put(point, component);
+                                 }
+                             }
+                             s.release();
+                         }
+                     });
+
+                     synchronized (result.routeGraphConnectionSet) {
+                         result.routeGraphConnectionSet.add(component);
+                     }
+                 } else {
+                     g.asyncRequest(new ConnectionPartRequest(errorHandler, DIA, component),
+                             new ProcedureAdapter<ConnectionPartData>() {
+                         @Override
+                         public void execute(ConnectionPartData partData) {
+                             synchronized (result) {
+                                 for (EdgeResource er : partData.edges) {
+                                     result.connectionSegments.add(er);
+                                     result.partToConnection.put(er, component);
+                                     result.connectionToParts.add(component, er);
+                                 }
+                                 for (Resource bp : partData.branchPoints) {
+                                     result.branchPoints.add(bp);
+                                     result.connectionToParts.add(component, bp);
+                                     result.partToConnection.put(bp, component);
+                                 }
+                             }
+                             s.release();
+                         }
+                     });
+
+                     synchronized (result.connectionSet) {
+                         result.connectionSet.add(component);
+                     }
+                 }
+             }
+             else if (types.contains(DIA.Element)) {
+                 synchronized (result.nodeSet) {
+                     result.nodeSet.add(component);
+                 }
+                 s.release();
+
+             }
+             else {
+                 synchronized (unrecognizedElementIndices) {
+                     // Unrecognized element, mark it to be
+                     // removed after everything is processed.
+                     unrecognizedElementIndices.add(elementIndex);
+                 }
+                 s.release();
+             }         
+               
+        }
+        
+        try {
+                       s.waitFor(components.size());
+               } catch (InterruptedException e) {
+                       e.printStackTrace();
+               }
+        
+        // Remove elements that were not recognized in descending order.
+        unrecognizedElementIndices.sort();
+        unrecognizedElementIndices.forEachDescending(new TIntProcedure() {
             @Override
-            public void finished(AsyncReadGraph graph) {
-                // Remove elements that were not recognized in descending order.
-                unrecognizedElementIndices.sort();
-                unrecognizedElementIndices.forEachDescending(new TIntProcedure() {
-                    @Override
-                    public boolean execute(int index) {
-                        result.elements.remove(index);
-                        return true;
-                    }
-                });
-
-                // Help successive request executions by remembering the previous
-                // element count. This will relieve some ArrayList reallocation
-                // strain down the road.
-                previousElementCount = result.elements.size();
-            }
-
-            @Override
-            public void exception(AsyncReadGraph graph, Throwable t) {
-                if (errorHandler != null)
-                    errorHandler.error(t.getMessage(), t);
+            public boolean execute(int index) {
+                result.elements.remove(index);
+                return true;
             }
         });
 
+        // Help successive request executions by remembering the previous
+        // element count. This will relieve some ArrayList reallocation
+        // strain down the road.
+        previousElementCount = result.elements.size();
+        
+
+//        g.forOrderedSet(data, new AsyncMultiProcedure<Resource>() {
+//
+//            @Override
+//            public void execute(AsyncReadGraph graph, final Resource component) {
+//
+//                graph.forTypes(component, new AsyncProcedure<Set<Resource>>() {
+//
+//                    @Override
+//                    public void exception(AsyncReadGraph graph, Throwable t) {
+//                        if (errorHandler != null)
+//                            errorHandler.error(t.getMessage(), t);
+//                    }
+//
+//                    @Override
+//                    public void execute(AsyncReadGraph graph, Set<Resource> types) {
+//                       
+//                    }
+//
+//                });
+//
+//            }
+//
+//            @Override
+//            public void finished(AsyncReadGraph graph) {
+//            }
+//
+//            @Override
+//            public void exception(AsyncReadGraph graph, Throwable t) {
+//                if (errorHandler != null)
+//                    errorHandler.error(t.getMessage(), t);
+//            }
+//        });
+
         return result;
     }
 }
\ No newline at end of file
index dd6c9b7d10f7e7e916264a30bc3f24af71180627..3e404cf565b96163ad27d1c3532169e14b243bd8 100644 (file)
@@ -1302,6 +1302,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                     // ITask task5 = ThreadLogger.getInstance().begin("DiagramContentRequest2");
                     ITask task42 = ThreadLogger.getInstance().begin("DiagramContentRequest2");
                     DiagramContents contents = g.syncRequest(query);
+                    System.err.println("contents: " + contents);
                     task42.finish();
                     // task5.finish();
                     monitor.worked(10);
@@ -1623,7 +1624,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
             this.removedRouteGraphConnections.clear();
         }
 
-        void processNodes(AsyncReadGraph graph) {
+        void processNodes(ReadGraph graph) throws DatabaseException {
 
             for (Map.Entry<Resource, Change> entry : changes.elements.entrySet()) {
 
@@ -1635,7 +1636,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                         IElement mappedElement = getMappedElement(element);
                         if (mappedElement == null) {
                             if (DebugPolicy.DEBUG_NODE_LOAD)
-                                graph.asyncRequest(new ReadRequest() {
+                                graph.syncRequest(new ReadRequest() {
                                     @Override
                                     public void run(ReadGraph graph) throws DatabaseException {
                                         System.out.println("    EXTERNALLY ADDED ELEMENT: "
@@ -1699,7 +1700,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                                     }
                                 };
 
-                                graph.asyncRequest(new ConnectionRequest(canvas, diagram, element, errorHandler, loadListener), new AsyncProcedure<IElement>() {
+                                graph.syncRequest(new ConnectionRequest(canvas, diagram, element, errorHandler, loadListener), new AsyncProcedure<IElement>() {
                                     @Override
                                     public void execute(AsyncReadGraph graph, final IElement e) {
                                         if (e == null)
@@ -1792,7 +1793,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                                 };
 
                                 //System.out.println("NODE REQUEST: " + element);
-                                graph.asyncRequest(new NodeRequest(canvas, diagram, element, loadListener), new AsyncProcedure<IElement>() {
+                                graph.syncRequest(new NodeRequest(canvas, diagram, element, loadListener), new AsyncProcedure<IElement>() {
                                     @Override
                                     public void execute(AsyncReadGraph graph, IElement e) {
                                         if (e == null)
@@ -1826,7 +1827,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                     case REMOVED: {
                         IElement e = getMappedElement(element);
                         if (DebugPolicy.DEBUG_NODE_LOAD)
-                            graph.asyncRequest(new ReadRequest() {
+                            graph.syncRequest(new ReadRequest() {
                                 @Override
                                 public void run(ReadGraph graph) throws DatabaseException {
                                     System.out.println("    EXTERNALLY REMOVED ELEMENT: "
@@ -1932,7 +1933,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
             }
         }
 
-        void processRouteGraphConnections(AsyncReadGraph graph) {
+        void processRouteGraphConnections(ReadGraph graph) throws DatabaseException {
             for (Map.Entry<Resource, Change> entry : changes.routeGraphConnections.entrySet()) {
                 final Resource connection = entry.getKey();
 
@@ -2010,7 +2011,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                             }
                         };
 
-                        graph.asyncRequest(new ConnectionRequest(canvas, diagram, connection, errorHandler, loadListener), new Procedure<IElement>() {
+                        graph.syncRequest(new ConnectionRequest(canvas, diagram, connection, errorHandler, loadListener), new Procedure<IElement>() {
                             @Override
                             public void execute(final IElement e) {
                                 if (e == null)
@@ -2052,7 +2053,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
             return assertMappedConnection(connection);
         }
 
-        void processBranchPoints(AsyncReadGraph graph) {
+        void processBranchPoints(ReadGraph graph) throws DatabaseException {
             for (Map.Entry<Resource, Change> entry : changes.branchPoints.entrySet()) {
 
                 final Resource element = entry.getKey();
@@ -2063,7 +2064,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                         IElement mappedElement = getMappedElement(element);
                         if (mappedElement == null) {
                             if (DebugPolicy.DEBUG_NODE_LOAD)
-                                graph.asyncRequest(new ReadRequest() {
+                                graph.syncRequest(new ReadRequest() {
                                     @Override
                                     public void run(ReadGraph graph) throws DatabaseException {
                                         System.out.println("    EXTERNALLY ADDED BRANCH POINT: "
@@ -2115,7 +2116,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                                 }
                             };
 
-                            graph.asyncRequest(new NodeRequest(canvas, diagram, element, loadListener), new AsyncProcedure<IElement>() {
+                            graph.syncRequest(new NodeRequest(canvas, diagram, element, loadListener), new AsyncProcedure<IElement>() {
                                 @Override
                                 public void execute(AsyncReadGraph graph, IElement e) {
                                     if (e != null) {
@@ -2141,7 +2142,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                     case REMOVED: {
                         IElement e = getMappedElement(element);
                         if (DebugPolicy.DEBUG_NODE_LOAD)
-                            graph.asyncRequest(new ReadRequest() {
+                            graph.syncRequest(new ReadRequest() {
                                 @Override
                                 public void run(ReadGraph graph) throws DatabaseException {
                                     System.out.println("    EXTERNALLY REMOVED BRANCH POINT: "
@@ -2158,7 +2159,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
             }
         }
 
-        void processConnectionSegments(AsyncReadGraph graph) {
+        void processConnectionSegments(ReadGraph graph) throws DatabaseException {
             ConnectionSegmentAdapter adapter = connectionSegmentAdapter;
 
             for (Map.Entry<EdgeResource, Change> entry : changes.connectionSegments.entrySet()) {
@@ -2170,7 +2171,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                         IElement mappedElement = getMappedElement(seg);
                         if (mappedElement == null) {
                             if (DebugPolicy.DEBUG_EDGE_LOAD)
-                                graph.asyncRequest(new ReadRequest() {
+                                graph.syncRequest(new ReadRequest() {
                                     @Override
                                     public void run(ReadGraph graph) throws DatabaseException {
                                         System.out.println("    EXTERNALLY ADDED CONNECTION SEGMENT: " + seg.toString()
@@ -2178,7 +2179,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                                     }
                                 });
 
-                            graph.asyncRequest(new EdgeRequest(canvas, errorHandler, canvasListenerSupport, diagram, adapter, seg), new AsyncProcedure<IElement>() {
+                            graph.syncRequest(new EdgeRequest(canvas, errorHandler, canvasListenerSupport, diagram, adapter, seg), new AsyncProcedure<IElement>() {
                                 @Override
                                 public void execute(AsyncReadGraph graph, IElement e) {
                                     if (DebugPolicy.DEBUG_EDGE_LOAD)
@@ -2206,7 +2207,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                     case REMOVED: {
                         final IElement e = getMappedElement(seg);
                         if (DebugPolicy.DEBUG_EDGE_LOAD)
-                            graph.asyncRequest(new ReadRequest() {
+                            graph.syncRequest(new ReadRequest() {
                                 @Override
                                 public void run(ReadGraph graph) throws DatabaseException {
                                     System.out.println("    EXTERNALLY REMOVED CONNECTION SEGMENT: " + seg.toString() + " - "
@@ -2260,9 +2261,9 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
             Object task = Timing.BEGIN("processNodesConnections");
             //System.out.println("---- PROCESS NODES & CONNECTIONS BEGIN");
             if (!changes.elements.isEmpty()) {
-                graph.syncRequest(new AsyncReadRequest() {
+                graph.syncRequest(new ReadRequest() {
                     @Override
-                    public void run(AsyncReadGraph graph) {
+                    public void run(ReadGraph graph) throws DatabaseException {
                         processNodes(graph);
                     }
                     @Override
@@ -2277,9 +2278,9 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
 
             //System.out.println("---- PROCESS BRANCH POINTS BEGIN");
             if (!changes.branchPoints.isEmpty()) {
-                graph.syncRequest(new AsyncReadRequest() {
+                graph.syncRequest(new ReadRequest() {
                     @Override
-                    public void run(AsyncReadGraph graph) {
+                    public void run(ReadGraph graph) throws DatabaseException {
                         processBranchPoints(graph);
                     }
                     @Override
@@ -2295,9 +2296,9 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
 
             //System.out.println("---- PROCESS CONNECTION SEGMENTS BEGIN");
             if (!changes.connectionSegments.isEmpty()) {
-                graph.syncRequest(new AsyncReadRequest() {
+                graph.syncRequest(new ReadRequest() {
                     @Override
-                    public void run(AsyncReadGraph graph) {
+                    public void run(ReadGraph graph) throws DatabaseException {
                         processConnectionSegments(graph);
                     }
                     @Override
@@ -2312,9 +2313,9 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
 
             task = Timing.BEGIN("processRouteGraphConnections");
             if (!changes.routeGraphConnections.isEmpty()) {
-                graph.syncRequest(new AsyncReadRequest() {
+                graph.syncRequest(new ReadRequest() {
                     @Override
-                    public void run(AsyncReadGraph graph) {
+                    public void run(ReadGraph graph) throws DatabaseException {
                         processRouteGraphConnections(graph);
                     }
                     @Override