From: jsimomaa Date: Mon, 16 Oct 2017 20:31:41 +0000 (+0300) Subject: Cluster loading problem fix made by Antti X-Git-Tag: v1.31.0~115 X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=commitdiff_plain;h=cec265e1216a0a211e6e6dc4f91d5fda4c5747db;ds=sidebyside Cluster loading problem fix made by Antti It was possible that at first a proxy cluster was created and that was used after the initial cluster was created. Therefore ensure that proxied clusters are actually loaded. More technical details from Antti refs #7554 Change-Id: I2867eddb69addba7f24b7c5d1bd4825c94f7aa75 --- diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ClusterChangeManager.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ClusterChangeManager.java index 830881355..048a77519 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ClusterChangeManager.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ClusterChangeManager.java @@ -41,7 +41,7 @@ public class ClusterChangeManager { if(clusterChanges.add(change)) { removeList.add(change); } else { - new Exception("trying to add change that already exists").printStackTrace(); + new Exception("trying to add change that already exists " + change.clusterUID + " " + System.identityHashCode(change.clusterImpl)).printStackTrace(); } updateChangeCounters(); } diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ClusterTable.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ClusterTable.java index 40b2530f2..123f346a4 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ClusterTable.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ClusterTable.java @@ -22,9 +22,9 @@ import java.util.concurrent.Semaphore; import org.simantics.databoard.Bindings; import org.simantics.db.ClusterCreator; import org.simantics.db.Database; +import org.simantics.db.Database.Session.ClusterChanges; import org.simantics.db.DevelopmentKeys; import org.simantics.db.SessionVariables; -import org.simantics.db.Database.Session.ClusterChanges; import org.simantics.db.common.utils.Logger; import org.simantics.db.exception.ClusterDoesNotExistException; import org.simantics.db.exception.DatabaseException; @@ -529,17 +529,19 @@ public final class ClusterTable implements IClusterTable { ClusterImpl getNewResourceCluster(ClusterSupport cs, GraphSession graphSession, boolean writeOnly) throws DatabaseException { + ClusterImpl result = null; if (Constants.NewClusterId == newResourceClusterId) { newResourceClusterId = graphSession.newClusterId(); - return getClusterByClusterIdOrMake(newResourceClusterId, writeOnly); + result = getClusterByClusterIdOrMake(newResourceClusterId, writeOnly); } else { ClusterImpl cluster = getClusterByClusterIdOrThrow(newResourceClusterId); if (cluster.getNumberOfResources(cs) >= CLUSTER_FILL_SIZE) { newResourceClusterId = graphSession.newClusterId(); cluster = getClusterByClusterIdOrMake(newResourceClusterId, writeOnly); } - return cluster; + result = cluster; } + return ensureLoaded(result); } void flushCluster(GraphSession graphSession) { @@ -818,25 +820,9 @@ public final class ClusterTable implements IClusterTable { TLongIntHashMap clusterLoadHistogram = new TLongIntHashMap(); int clusterLoadCounter = 0; - @SuppressWarnings("unchecked") - public final T getClusterByResourceKey(final int resourceKey) { - int clusterKey = ClusterTraitsBase.getClusterKeyFromResourceKeyNoThrow(resourceKey); - if (ClusterTraitsBase.isVirtualClusterKey(clusterKey)) - throw new RuntimeException("Tried to get a persistent cluster for a virtual resource."); - ClusterI c = clusterArray[clusterKey]; - if (c == null) - return null; - if (c.isLoaded()) { - if ((counter++ & 4095) == 0) - refreshImportance((ClusterImpl) c); - return (T) c; - } - if (!(c instanceof ClusterSmall)) { - Logger.defaultLogError("Proxy must be instance of ClusterSmall"); - return null; - } + private T ensureLoaded(T c) { ClusterI cluster; - ClusterSmall cs = (ClusterSmall) c; + ClusterImpl cs = (ClusterImpl) c; try { if(DebugPolicy.REPORT_CLUSTER_LOADING) { long start = System.nanoTime(); @@ -861,13 +847,32 @@ public final class ClusterTable implements IClusterTable { Logger.defaultLogError(e); if (DebugPolicy.REPORT_CLUSTER_EVENTS) e.printStackTrace(); - String msg = "Failed to load cluster " + cs.getClusterUID() + " for resource key " + resourceKey - + " resourceId=" + (((cs.getClusterId() << 16 + (resourceKey & 65535)))); + String msg = "Failed to load cluster " + cs.getClusterUID();// + " resourceId=" + (((cs.getClusterId() << 16 + (resourceKey & 65535)))); // TODO: this jams the system => needs refactoring. throw new RuntimeDatabaseException(msg, e); } return (T) cluster; } + + @SuppressWarnings("unchecked") + public final T getClusterByResourceKey(final int resourceKey) { + int clusterKey = ClusterTraitsBase.getClusterKeyFromResourceKeyNoThrow(resourceKey); + if (ClusterTraitsBase.isVirtualClusterKey(clusterKey)) + throw new RuntimeException("Tried to get a persistent cluster for a virtual resource."); + ClusterI c = clusterArray[clusterKey]; + if (c == null) + return null; + if (c.isLoaded()) { + if ((counter++ & 4095) == 0) + refreshImportance((ClusterImpl) c); + return (T) c; + } + if (!(c instanceof ClusterSmall)) { + Logger.defaultLogError("Proxy must be instance of ClusterSmall"); + return null; + } + return ensureLoaded((T)c); + } @SuppressWarnings("unchecked") final T checkedGetClusterByResourceKey(final int resourceKey) { diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplSocket.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplSocket.java index c286f02c7..2ff47c292 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplSocket.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplSocket.java @@ -849,14 +849,17 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule private void maintainCluster(ClusterImpl before, ClusterI after_) { if(after_ != null && after_ != before) { ClusterImpl after = (ClusterImpl)after_; - if(currentCluster == before) currentCluster = after; + if(currentCluster == before) { + currentCluster = after; + } clusterTable.replaceCluster(after); } } public int createResourceKey(int foreignCounter) throws DatabaseException { - if(currentCluster == null) + if(currentCluster == null) { currentCluster = getNewResourceCluster(); + } if(currentCluster.getNumberOfResources(clusterTranslator) == ClusterTable.CLUSTER_FILL_SIZE) { ClusterWriteOnly newCluster = (ClusterWriteOnly)getNewResourceCluster(); newCluster.foreignLookup = new byte[foreignCounter];