Diagram loading concurrency problem with Sysdyn 10/2910/1
authorAntti Villberg <antti.villberg@semantum.fi>
Tue, 28 May 2019 11:30:25 +0000 (14:30 +0300)
committerAntti Villberg <antti.villberg@semantum.fi>
Tue, 28 May 2019 11:30:25 +0000 (14:30 +0300)
gitlab #300

Change-Id: I6c92e9ac4d1628a25588d7b7005e5e9be967f700

bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryProcessor.java
bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/EdgeRequest.java
bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/GraphToDiagramSynchronizer.java

index b2951cb27e3c122322aeca97aabe124cac8b9702..5a37257e2531c051c39de0bea04af271e1adccce 100644 (file)
@@ -2296,67 +2296,16 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap
        @Override
        final public void forEachPredicate(final ReadGraphImpl impl, final Resource subject, final AsyncMultiProcedure<Resource> procedure) {
 
-               throw new UnsupportedOperationException();
+        try {
 
-//             assert(subject != null);
-//             assert(procedure != null);
-//
-//             final ListenerBase listener = getListenerBase(procedure);
-//
-//             IntProcedure ip = new IntProcedure() {
-//
-//                     AtomicBoolean first = new AtomicBoolean(true);
-//
-//                     @Override
-//                     public void execute(ReadGraphImpl graph, int i) {
-//                             try {
-//                                     if(first.get()) {
-//                                             procedure.execute(graph, querySupport.getResource(i));
-//                                     } else {
-//                                             procedure.execute(impl.newRestart(graph), querySupport.getResource(i));
-//                                     }
-//                             } catch (Throwable t2) {
-//                                     Logger.defaultLogError(t2);
-//                             }
-//                     }
-//
-//                     @Override
-//                     public void finished(ReadGraphImpl graph) {
-//                             try {
-//                                     if(first.compareAndSet(true, false)) {
-//                                             procedure.finished(graph);
-////                                           impl.state.barrier.dec(this);
-//                                     } else {
-//                                             procedure.finished(impl.newRestart(graph));
-//                                     }
-//
-//                             } catch (Throwable t2) {
-//                                     Logger.defaultLogError(t2);
-//                             }
-//                     }
-//
-//                     @Override
-//                     public void exception(ReadGraphImpl graph, Throwable t) {
-//                             try {
-//                                     if(first.compareAndSet(true, false)) {
-//                                             procedure.exception(graph, t);
-//                                     } else {
-//                                             procedure.exception(impl.newRestart(graph), t);
-//                                     }
-//                             } catch (Throwable t2) {
-//                                     Logger.defaultLogError(t2);
-//                             }
-//                     }
-//
-//             };
-//
-//             int sId = querySupport.getId(subject);
-//
-//             try {
-//                     QueryCache.runnerPredicates(impl, sId, impl.parent, listener, ip);
-//             } catch (DatabaseException e) {
-//                     Logger.defaultLogError(e);
-//             }
+               for(Resource predicate : getPredicates(impl, subject))
+                   procedure.execute(impl, predicate);
+
+               procedure.finished(impl);
+
+           } catch (Throwable e) {
+               procedure.exception(impl, e);
+           }
 
        }
 
index 651228ce1d7756f10516430c6bbc8c71d355cece..826827f768c3cf4a4b06578c72fe2537d9f6c23b 100644 (file)
@@ -16,6 +16,7 @@ import org.simantics.db.common.procedure.adapter.ListenerSupport;
 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
 import org.simantics.db.procedure.AsyncProcedure;
 import org.simantics.diagram.content.EdgeResource;
+import org.simantics.diagram.internal.DebugPolicy;
 import org.simantics.diagram.stubs.DiagramResource;
 import org.simantics.diagram.synchronization.ErrorHandler;
 import org.simantics.g2d.canvas.ICanvasContext;
@@ -30,16 +31,19 @@ import org.simantics.g2d.element.impl.Element;
  */
 public class EdgeRequest extends BaseRequest2<EdgeResource, IElement> {
 
+    final GraphToDiagramSynchronizer synchronizer;
     final ErrorHandler errorHandler;
     final ListenerSupport listenerSupport;
     final IDiagram diagram;
     final ConnectionSegmentAdapter adapter;
 
-    public EdgeRequest(ICanvasContext canvas, ErrorHandler errorHandler, ListenerSupport listenerSupport, IDiagram diagram, ConnectionSegmentAdapter adapter, EdgeResource resource) {
+    public EdgeRequest(GraphToDiagramSynchronizer synchronizer, ICanvasContext canvas, ErrorHandler errorHandler, ListenerSupport listenerSupport, IDiagram diagram, ConnectionSegmentAdapter adapter, EdgeResource resource) {
         super(canvas, resource);
 
         assert(adapter != null);
+        assert(synchronizer != null);
 
+        this.synchronizer = synchronizer;
         this.errorHandler = errorHandler;
         this.listenerSupport = listenerSupport;
         this.diagram = diagram;
@@ -96,6 +100,13 @@ public class EdgeRequest extends BaseRequest2<EdgeResource, IElement> {
 
                                     @Override
                                     public void execute(AsyncReadGraph graph, IElement element) {
+                                        
+                                        if (DebugPolicy.DEBUG_EDGE_LOAD)
+                                            System.out.println("    SPAWNED EDGE SEGMENT: " + element + " " + data);
+
+                                        // Register this for updates to work correctly
+                                        synchronizer.mapElementIfNew(data, element);
+                                        
 //                                        task.finish();
                                         // Tell the procedure to use this element
                                         procedure.execute(graph, element);
index aa35c63342c28e8d952a7989f2cc5edd26f83f21..03cedfcb39a66cae558ccd27f0431bffa3dadadf 100644 (file)
@@ -616,6 +616,17 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
      */
     ConcurrentMap<Object, ConnectionEntityImpl> dataConnection = new ConcurrentHashMap<Object, ConnectionEntityImpl>();
 
+
+    void mapElementIfNew(final Object data, final IElement element) {
+        IElement mapped = getMappedElement(data);
+        if(mapped == null) {
+            mapElement(data, element);
+            currentUpdater.addedElements.add(element);
+            currentUpdater.addedElementMap.put(data, element);
+        }
+    }
+
+    
     /**
      * @param data
      * @param element
@@ -1744,9 +1755,15 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                                             @Override
                                             public void execute(Resource connectionType) {
                                                 synchronized (GraphToDiagramUpdater.this) {
+                                                    IElement mapped = getMappedElement(element);
+                                                    assert(mapped != null);
+                                                    
+                                                    if (DebugPolicy.DEBUG_CONNECTION_LISTENER)
+                                                        System.out.println("CONNECTION ENTITY CREATED " + e + " " + element);
+
                                                     //System.out.println("new connection entity " + e);
-                                                    ConnectionEntityImpl entity = new ConnectionEntityImpl(element, connectionType, e);
-                                                    e.setHint(ElementHints.KEY_CONNECTION_ENTITY, entity);
+                                                    ConnectionEntityImpl entity = new ConnectionEntityImpl(element, connectionType, mapped);
+                                                    mapped.setHint(ElementHints.KEY_CONNECTION_ENTITY, entity);
                                                     addedConnectionEntities.put(element, entity);
                                                 }
                                             }
@@ -2223,13 +2240,13 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                                     }
                                 });
 
-                            graph.syncRequest(new EdgeRequest(canvas, errorHandler, canvasListenerSupport, diagram, adapter, seg), new AsyncProcedure<IElement>() {
+                            graph.syncRequest(new EdgeRequest(GraphToDiagramSynchronizer.this, canvas, errorHandler, canvasListenerSupport, diagram, adapter, seg), new AsyncProcedure<IElement>() {
                                 @Override
                                 public void execute(AsyncReadGraph graph, IElement e) {
                                     if (DebugPolicy.DEBUG_EDGE_LOAD)
-                                        System.out.println("ADDED EDGE LOADED: " + e);
+                                        System.out.println("ADDED EDGE LOADED: " + e + " " + seg);
+
                                     if (e != null) {
-                                        mapElement(seg, e);
                                         synchronized (GraphToDiagramUpdater.this) {
                                             addedConnectionSegments.add(e);
                                             addedElementMap.put(seg, e);
@@ -2428,8 +2445,6 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                     @Override
                     public void execute(IElement loaded) {
                         // Invoked when the element has been loaded.
-                        if (DebugPolicy.DEBUG_EDGE_LISTENER)
-                            System.out.println("EDGE LoadListener for " + loaded);
 
                         if (loaded == null) {
                             disposeListener();
@@ -2437,6 +2452,10 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                         }
 
                         Object data = loaded.getHint(ElementHints.KEY_OBJECT);
+
+                        if (DebugPolicy.DEBUG_EDGE_LISTENER)
+                            System.out.println("EDGE LoadListener for " + loaded + " " + data);
+
                         if (addedElementMap.containsKey(data)) {
                             // This element was just loaded, in
                             // which case its hints need to