X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.acorn%2Fsrc%2Forg%2Fsimantics%2Facorn%2FGraphClientImpl2.java;h=d8b6552ffc68bbc40c90788766142ff687ccba08;hb=f6fb0a91cda199e59cece4319cedad0befce8bdc;hp=7a57053bcf6aa9f1af09548424bfe00c59456751;hpb=751ee12501d220832b672dd433655a4d65806fd9;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.acorn/src/org/simantics/acorn/GraphClientImpl2.java b/bundles/org.simantics.acorn/src/org/simantics/acorn/GraphClientImpl2.java index 7a57053bc..d8b6552ff 100644 --- a/bundles/org.simantics.acorn/src/org/simantics/acorn/GraphClientImpl2.java +++ b/bundles/org.simantics.acorn/src/org/simantics/acorn/GraphClientImpl2.java @@ -45,19 +45,23 @@ import org.simantics.db.exception.SDBException; import org.simantics.db.server.ProCoreException; import org.simantics.db.service.ClusterSetsSupport; import org.simantics.db.service.ClusterUID; +import org.simantics.db.service.EventSupport; import org.simantics.db.service.LifecycleSupport; -import org.simantics.utils.DataContainer; import org.simantics.utils.datastructures.Pair; import org.simantics.utils.logging.TimeLogger; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import fi.vtt.simantics.procore.internal.EventSupportImpl; import gnu.trove.map.hash.TLongObjectHashMap; public class GraphClientImpl2 implements Database.Session { private static final Logger LOGGER = LoggerFactory.getLogger(GraphClientImpl2.class); public static final boolean DEBUG = false; + + public static final String CLOSE = "close"; + public static final String PURGE = "purge"; final ClusterManager clusters; @@ -68,7 +72,9 @@ public class GraphClientImpl2 implements Database.Session { private Path dbFolder; private final Database database; private ServiceLocator locator; + private FileCache fileCache; private MainProgram mainProgram; + private EventSupportImpl eventSupport; private static class ClientThreadFactory implements ThreadFactory { @@ -92,13 +98,18 @@ public class GraphClientImpl2 implements Database.Session { this.database = database; this.dbFolder = dbFolder; this.locator = locator; - this.clusters = new ClusterManager(dbFolder); + this.fileCache = new FileCache(); + // This disposes the cache when the session is shut down + locator.registerService(FileCache.class, fileCache); + this.clusters = new ClusterManager(dbFolder, fileCache); load(); ClusterSetsSupport cssi = locator.getService(ClusterSetsSupport.class); cssi.setReadDirectory(clusters.lastSessionDirectory); cssi.updateWriteDirectory(clusters.workingDirectory); mainProgram = new MainProgram(this, clusters); executor.execute(mainProgram); + eventSupport = (EventSupportImpl)locator.getService(EventSupport.class); + } public Path getDbFolder() { @@ -213,6 +224,7 @@ public class GraphClientImpl2 implements Database.Session { throw new ProCoreException(e1); } closed = true; + eventSupport.fireEvent(CLOSE, null); } //impl.close(); } @@ -272,6 +284,11 @@ public class GraphClientImpl2 implements Database.Session { this.state = state; this.semaphore = semaphore; } + + @Override + public String toString() { + return getClass().getSimpleName() + "[state=" + state + ", semaphore=" + semaphore + "]"; + } } private class TransactionManager { @@ -374,6 +391,7 @@ public class GraphClientImpl2 implements Database.Session { return req; } + private long askWriteTransactionCount = 0; /* * This method cannot be synchronized since it waits and must support multiple entries * by query thread(s) and internal transactions such as snapshot saver @@ -384,7 +402,25 @@ public class GraphClientImpl2 implements Database.Session { TransactionRequest req = queue(TransactionState.WRITE, semaphore); try { - semaphore.acquire(); + while (true) { + boolean acquired = semaphore.tryAcquire(1, TimeUnit.MINUTES); + if (!acquired) { + if (askWriteTransactionCount < 10) { + LOGGER.error("Could not acquire semaphore for askWriteTransaction for TransactionRequest {}", req); + LOGGER.error("Current clusters.state.headChangeSetId is {}", clusters.state.headChangeSetId); + LOGGER.error("Current clusters.state.transactionId is {}", clusters.state.transactionId); + LOGGER.error("Current amount of requests is {}", requests.size()); + if (requests.size() < 100) { + LOGGER.error("Current requests {}", requests); + } + LOGGER.error("Current transaction state is {}", currentTransactionState); + askWriteTransactionCount++; + } + } else { + askWriteTransactionCount = 0; + break; + } + } } catch (InterruptedException e) { throw new IllegalAcornStateException(e); } @@ -685,7 +721,7 @@ public class GraphClientImpl2 implements Database.Session { LOGGER.info("performUndo " + ccsid); performUndo(ccsid, clusterChanges, support); } catch (DatabaseException e) { - e.printStackTrace(); + LOGGER.error("failed to perform undo for cluster change set {}", ccsid, e); } } } @@ -794,8 +830,10 @@ public class GraphClientImpl2 implements Database.Session { unexpectedClose = true; } finally { try { - if(tr != null) + if(tr != null) { endTransaction(tr.getTransactionId()); + eventSupport.fireEvent(PURGE, null); + } if (unexpectedClose) { LifecycleSupport support = getServiceLocator().getService(LifecycleSupport.class); try {