import org.simantics.acorn.internal.ClusterChange;
import org.simantics.acorn.internal.ClusterUpdateProcessorBase;
import org.simantics.acorn.internal.UndoClusterUpdateProcessor;
+import org.simantics.acorn.lru.ClusterChangeSet.Entry;
import org.simantics.acorn.lru.ClusterInfo;
import org.simantics.acorn.lru.ClusterStreamChunk;
import org.simantics.acorn.lru.ClusterUpdateOperation;
-import org.simantics.acorn.lru.ClusterChangeSet.Entry;
import org.simantics.db.ClusterCreator;
import org.simantics.db.Database;
import org.simantics.db.ServiceLocator;
-import org.simantics.db.common.utils.Logger;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.exception.SDBException;
import org.simantics.db.server.ProCoreException;
import org.simantics.db.service.LifecycleSupport;
import org.simantics.utils.datastructures.Pair;
import org.simantics.utils.logging.TimeLogger;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
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 final ClusterManager clusters;
mainProgram.mutex.release();
}
} catch (IllegalAcornStateException | ProCoreException e) {
- Logger.defaultLogError("Snapshotting failed", e);
+ LOGGER.error("Snapshotting failed", e);
unexpectedClose = true;
} catch (InterruptedException e) {
- Logger.defaultLogError("Snapshotting interrupted", e);
+ LOGGER.error("Snapshotting interrupted", e);
} finally {
try {
if(tr != null)
try {
support.close();
} catch (DatabaseException e1) {
- Logger.defaultLogError("Failed to close database as a safety measure due to failed snapshotting", e1);
+ LOGGER.error("Failed to close database as a safety measure due to failed snapshotting", e1);
}
}
} catch (ProCoreException e) {
- Logger.defaultLogError("Failed to end snapshotting write transaction", e);
+ LOGGER.error("Failed to end snapshotting write transaction", e);
}
}
}
@Override
public void close() throws ProCoreException {
- System.err.println("Closing " + this + " and mainProgram " + mainProgram);
+ LOGGER.info("Closing " + this + " and mainProgram " + mainProgram);
if(!closed && !isClosing) {
isClosing = true;
try {
if (!unexpectedClose)
makeSnapshot(true);
-
+
mainProgram.close();
clusters.shutdown();
executor.shutdown();
boolean executorTerminated = executor.awaitTermination(500, TimeUnit.MILLISECONDS);
boolean saverTerminated = saver.awaitTermination(500, TimeUnit.MILLISECONDS);
- System.err.println("executorTerminated=" + executorTerminated + ", saverTerminated=" + saverTerminated);
-
+ LOGGER.info("executorTerminated=" + executorTerminated + ", saverTerminated=" + saverTerminated);
+
+ try {
+ clusters.mainState.save(dbFolder);
+ } catch (IOException e) {
+ LOGGER.error("Failed to save " + MainState.MAIN_STATE + " file in database folder " + dbFolder);
+ }
+
mainProgram = null;
executor = null;
saver = null;
clusters.state.headChangeSetId++;
return clusters.state.headChangeSetId;
} catch (SDBException e) {
- Logger.defaultLogError("Failed to undo cancelled transaction", e);
+ LOGGER.error("Failed to undo cancelled transaction", e);
throw new ProCoreException(e);
}
}
final int changeSetId = clusters.state.headChangeSetId;
if(ClusterUpdateProcessorBase.DEBUG)
- System.err.println(" === BEGIN UNDO ===");
+ LOGGER.info(" === BEGIN UNDO ===");
for(int i=0;i<changeSetIds.length;i++) {
final long id = changeSetIds[changeSetIds.length-1-i];
String ccsid = ccss.get(ccss.size()-j-1);
try {
if(ClusterUpdateProcessorBase.DEBUG)
- System.err.println("performUndo " + ccsid);
+ LOGGER.info("performUndo " + ccsid);
performUndo(ccsid, clusterChanges, support);
} catch (DatabaseException e) {
e.printStackTrace();
}
if(ClusterUpdateProcessorBase.DEBUG)
- System.err.println(" === END UNDO ===");
+ LOGGER.info(" === END UNDO ===");
for(int i=0;i<clusterChanges.size();i++) {
public boolean rolledback() {
return clusters.rolledback();
}
+
+ public void purge() throws IllegalAcornStateException {
+ clusters.purge(locator);
+ }
-
-
-
-
-
-
-
-
-
-
- ////////////////////////
-
-
-
-
-
-
-
-
-
-
-
-
+ public void purgeDatabase() {
+
+ if (isClosing || unexpectedClose)
+ return;
+
+ saver.execute(new Runnable() {
+
+ @Override
+ public void run() {
+ Transaction tr = null;
+ try {
+ // First take a write transaction
+ tr = askWriteTransaction(-1);
+ // Then make sure that MainProgram is idling
+ mainProgram.mutex.acquire();
+ try {
+ synchronized(mainProgram) {
+ if(mainProgram.operations.isEmpty()) {
+ purge();
+ } else {
+ // MainProgram is becoming busy again - delay snapshotting
+ return;
+ }
+ }
+ } finally {
+ mainProgram.mutex.release();
+ }
+ } catch (IllegalAcornStateException | ProCoreException e) {
+ LOGGER.error("Purge failed", e);
+ unexpectedClose = true;
+ } catch (InterruptedException e) {
+ LOGGER.error("Purge interrupted", e);
+ } finally {
+ try {
+ if(tr != null)
+ endTransaction(tr.getTransactionId());
+ if (unexpectedClose) {
+ LifecycleSupport support = getServiceLocator().getService(LifecycleSupport.class);
+ try {
+ support.close();
+ } catch (DatabaseException e1) {
+ LOGGER.error("Failed to close database as a safety measure due to failed purge", e1);
+ }
+ }
+ } catch (ProCoreException e) {
+ LOGGER.error("Failed to end purge write transaction", e);
+ }
+ }
+ }
+ });
+
+ }
+
+ public long getTailChangeSetId() {
+ return clusters.getTailChangeSetId();
+ }
+
}