X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.db.layer0%2Fsrc%2Forg%2Fsimantics%2Fdb%2Flayer0%2Fvariable%2FNodeStructureRequest.java;h=707fdbd0ee46463a586eda41827beb5b9118085f;hp=a87a2042a9452cbe8e187b352f47da116b8f9d8c;hb=ccb253462b54a0e036f0906ec8ac11a9021a968c;hpb=969bd23cab98a79ca9101af33334000879fb60c5 diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/NodeStructureRequest.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/NodeStructureRequest.java index a87a2042a..707fdbd0e 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/NodeStructureRequest.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/NodeStructureRequest.java @@ -1,180 +1,183 @@ -package org.simantics.db.layer0.variable; - -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import org.simantics.databoard.util.ObjectUtils; -import org.simantics.db.ReadGraph; -import org.simantics.db.common.request.ParametrizedPrimitiveRead; -import org.simantics.db.common.utils.Logger; -import org.simantics.db.exception.DatabaseException; -import org.simantics.db.layer0.variable.Variables.NodeStructure; -import org.simantics.db.procedure.Listener; -import org.simantics.simulator.variable.exceptions.NodeManagerException; - -import gnu.trove.map.hash.THashMap; - -@SuppressWarnings("rawtypes") -class NodeStructureRequest extends ParametrizedPrimitiveRead implements VariableNodeReadRunnable { - - private Listener listener = null; - private NodeStructure value = Variables.PENDING_NODE_STRUCTURE; - private boolean wasRun = false; - - static class Probe implements Runnable { - - private VariableNode node; - public NodeStructure result; - - public Probe(VariableNode node) { - this.node = node; - } - - @SuppressWarnings("unchecked") - @Override - public void run() { - try { - result = NodeStructureRequest.get(node); - node.support.structureCache.put(node.node, result, 1000000000L); - } catch (NodeManagerException e) { - e.printStackTrace(); - } - } - - } - - public NodeStructureRequest(VariableNode node) { - super(node); - } - - @SuppressWarnings("unchecked") - @Override - public void register(ReadGraph graph, final Listener procedure) { - - if(procedure.isDisposed()) { - - // We are not listening - NodeStructure result = (NodeStructure)parameter.support.structureCache.get(parameter.node); - - if(result != null) { - // Return cached value immediately - procedure.execute(result); - } else { - NodeStructureRequest.Probe probe = new Probe(parameter); - parameter.support.manager.getRealm().asyncExec(probe); - if(probe.result != null) { - procedure.execute(probe.result); - } else { - procedure.execute(Variables.PENDING_NODE_STRUCTURE); - } - } - - return; - - } - - // We need to listen - listener = procedure; - // Register listening - parameter.support.manager.addNodeListener(parameter.node, this); - synchronized(this) { - if(wasRun) { - procedure.execute(value); - } else { - NodeStructure result = (NodeStructure)parameter.support.structureCache.get(parameter.node); - if(result != null) { - procedure.execute(result); - } else { - procedure.execute(Variables.PENDING_NODE_STRUCTURE); - } - } - } - - } - - static class NodeListener implements VariableNodeReadRunnable { - - private VariableNode node; - private NodeStructureRequest request; - - public NodeListener(VariableNode node, NodeStructureRequest request) { - this.node = node; - this.request = request; - } - - @SuppressWarnings("unchecked") - @Override - public void run() { - node.support.manager.addNodeListener(node.node, request); - } - - } - - @SuppressWarnings("unchecked") - @Override - public void unregistered() { - parameter.support.manager.removeNodeListener(parameter.node, this); - parameter.support.structureCache.removeListening(parameter.node); - listener = null; - } - - @SuppressWarnings("unchecked") - public static NodeStructure get(VariableNode parameter) throws NodeManagerException { - List children = parameter.support.manager.getChildren(parameter.node); - List properties = parameter.support.manager.getProperties(parameter.node); - Map childMap = Collections.emptyMap(); - Map propertyMap = childMap; - if(!children.isEmpty()) { - childMap = new THashMap<>(children.size()); - for(Object o : children) { - String name = parameter.support.manager.getName(o); - childMap.put(name, o); - } - } - if(!properties.isEmpty()) { - propertyMap = new THashMap<>(properties.size()); - for(Object o : properties) { - String name = parameter.support.manager.getName(o); - propertyMap.put(name, o); - } - } - return new NodeStructure(childMap, propertyMap); - } - - @SuppressWarnings("unchecked") - @Override - public synchronized void run() { - try { - // Cache this value with infinite cache time since we are listening - NodeStructure newValue = get(parameter); - if (wasRun && ObjectUtils.objectEquals(value, newValue)) { - //System.out.println("CACHE VALUE MATCH (" + newValue + ") for " + node.node); - return; - } - value = newValue; - parameter.support.structureCache.put(parameter.node, value); - } catch (Throwable e) { - // Must catch everything to prevent DB client from getting stuck. - Logger.defaultLogError(e); - // Invoke the exception method of the listener - Listener listener = this.listener; - if (listener != null) listener.exception(new DatabaseException("External data access error", e)); - wasRun = true; - return; - } - - // Must always invoke an existing listener, regardless of earlier errors. - Listener listener = this.listener; - if (listener != null) { - listener.execute(value); - } - wasRun = true; - } - - @Override - public String toString() { - return "NodeStructureRequest.run @ " + System.identityHashCode(this); - } - +package org.simantics.db.layer0.variable; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.simantics.databoard.util.ObjectUtils; +import org.simantics.db.ReadGraph; +import org.simantics.db.common.request.ParametrizedPrimitiveRead; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variables.NodeStructure; +import org.simantics.db.procedure.Listener; +import org.simantics.simulator.variable.exceptions.NodeManagerException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import gnu.trove.map.hash.THashMap; + +@SuppressWarnings("rawtypes") +class NodeStructureRequest extends ParametrizedPrimitiveRead implements VariableNodeReadRunnable { + + private static final Logger LOGGER = LoggerFactory.getLogger(NodeStructureRequest.class); + + private Listener listener = null; + private NodeStructure value = Variables.PENDING_NODE_STRUCTURE; + private boolean wasRun = false; + + static class Probe implements Runnable { + + private VariableNode node; + public NodeStructure result; + + public Probe(VariableNode node) { + this.node = node; + } + + @SuppressWarnings("unchecked") + @Override + public void run() { + try { + result = NodeStructureRequest.get(node); + node.support.structureCache.put(node.node, result, 1000000000L); + } catch (NodeManagerException e) { + e.printStackTrace(); + } + } + + } + + public NodeStructureRequest(VariableNode node) { + super(node); + } + + @SuppressWarnings("unchecked") + @Override + public void register(ReadGraph graph, final Listener procedure) { + + if(procedure.isDisposed()) { + + // We are not listening + NodeStructure result = (NodeStructure)parameter.support.structureCache.get(parameter.node); + + if(result != null) { + // Return cached value immediately + procedure.execute(result); + } else { + NodeStructureRequest.Probe probe = new Probe(parameter); + parameter.support.manager.getRealm().asyncExec(probe); + if(probe.result != null) { + procedure.execute(probe.result); + } else { + procedure.execute(Variables.PENDING_NODE_STRUCTURE); + } + } + + return; + + } + + // We need to listen + listener = procedure; + // Register listening + parameter.support.manager.addNodeListener(parameter.node, this); + synchronized(this) { + if(!wasRun) { + NodeStructure result = (NodeStructure)parameter.support.structureCache.get(parameter.node); + if(result != null) { + procedure.execute(result); + } else { + procedure.execute(Variables.PENDING_NODE_STRUCTURE); + } + } + } + + } + + static class NodeListener implements VariableNodeReadRunnable { + + private VariableNode node; + private NodeStructureRequest request; + + public NodeListener(VariableNode node, NodeStructureRequest request) { + this.node = node; + this.request = request; + } + + @SuppressWarnings("unchecked") + @Override + public void run() { + node.support.manager.addNodeListener(node.node, request); + } + + } + + @SuppressWarnings("unchecked") + @Override + public void unregistered() { + parameter.support.manager.removeNodeListener(parameter.node, this); + parameter.support.structureCache.removeListening(parameter.node); + listener = null; + } + + @SuppressWarnings("unchecked") + public static NodeStructure get(VariableNode parameter) throws NodeManagerException { + List children = parameter.support.manager.getChildren(parameter.node); + List properties = parameter.support.manager.getProperties(parameter.node); + Map childMap = Collections.emptyMap(); + Map propertyMap = childMap; + if(!children.isEmpty()) { + childMap = new THashMap<>(children.size()); + for(Object o : children) { + String name = parameter.support.manager.getName(o); + childMap.put(name, o); + } + } + if(!properties.isEmpty()) { + propertyMap = new THashMap<>(properties.size()); + for(Object o : properties) { + String name = parameter.support.manager.getName(o); + propertyMap.put(name, o); + } + } + return new NodeStructure(childMap, propertyMap); + } + + @SuppressWarnings("unchecked") + @Override + public synchronized void run() { + try { + // Cache this value with infinite cache time since we are listening + NodeStructure newValue = get(parameter); + if (wasRun && ObjectUtils.objectEquals(value, newValue)) { + //System.out.println("CACHE VALUE MATCH (" + newValue + ") for " + node.node); + return; + } + value = newValue; + parameter.support.structureCache.put(parameter.node, value); + } catch (Throwable e) { + // Must catch everything to prevent DB client from getting stuck. + LOGGER.error("Error while computing node structure", e); + // Invoke the exception method of the listener + Listener listener = this.listener; + if (listener != null) { + listener.exception(new DatabaseException("External data access error", e)); + wasRun = true; + } + return; + } + + // Must always invoke an existing listener, regardless of earlier errors. + Listener listener = this.listener; + if (listener != null) { + listener.execute(value); + wasRun = true; + } + } + + @Override + public String toString() { + return "NodeStructureRequest.run @ " + System.identityHashCode(this); + } + } \ No newline at end of file