From: Tuukka Lehtonen Date: Tue, 6 Sep 2016 11:45:06 +0000 (+0300) Subject: Merge "Some Acorn improvements" X-Git-Tag: v1.25.0~135 X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=commitdiff_plain;h=d77257f045bacb676d276fe3a702e43e3a4eada3;hp=0e10b76b1c4d4d1828ac93ab2933acfa03785f78 Merge "Some Acorn improvements" --- diff --git a/bundles/org.simantics.acorn/src/org/simantics/acorn/AcornDriver.java b/bundles/org.simantics.acorn/src/org/simantics/acorn/AcornDriver.java index 0e6d52b9a..99ec49062 100644 --- a/bundles/org.simantics.acorn/src/org/simantics/acorn/AcornDriver.java +++ b/bundles/org.simantics.acorn/src/org/simantics/acorn/AcornDriver.java @@ -65,38 +65,7 @@ public class AcornDriver implements Driver { @Override public ServerI getServer(String address, Properties properties) throws DatabaseException { - return new ServerI() { - - @Override - public void stop() throws DatabaseException { - // nop - } - - @Override - public void start() throws DatabaseException { - // nop - } - - @Override - public boolean isActive() throws DatabaseException { - return true; - } - - @Override - public String getAddress() throws DatabaseException { - return address; - } - - @Override - public String executeAndDisconnect(String command) throws DatabaseException { - return ""; - } - - @Override - public String execute(String command) throws DatabaseException { - return ""; - } - }; + return new AcornServerI(address); } @Override @@ -104,5 +73,44 @@ public class AcornDriver implements Driver { Path dbFolder = Paths.get(address); return new AcornManagement(dbFolder, properties); } + + private static class AcornServerI implements ServerI { + + private String address; + + public AcornServerI(String address) { + this.address = address; + } + + @Override + public void stop() throws DatabaseException { + AcornDatabaseManager.getDatabase(Paths.get(address)).tryToStop(); + } + + @Override + public void start() throws DatabaseException { + AcornDatabaseManager.getDatabase(Paths.get(address)).start(); + } + + @Override + public boolean isActive() throws DatabaseException { + return AcornDatabaseManager.getDatabase(Paths.get(address)).isRunning(); + } + + @Override + public String getAddress() throws DatabaseException { + return address; + } + + @Override + public String executeAndDisconnect(String command) throws DatabaseException { + return ""; + } + + @Override + public String execute(String command) throws DatabaseException { + return ""; + } + } } diff --git a/bundles/org.simantics.acorn/src/org/simantics/acorn/AcornManagement.java b/bundles/org.simantics.acorn/src/org/simantics/acorn/AcornManagement.java index 561a03913..a7bccf087 100644 --- a/bundles/org.simantics.acorn/src/org/simantics/acorn/AcornManagement.java +++ b/bundles/org.simantics.acorn/src/org/simantics/acorn/AcornManagement.java @@ -34,7 +34,7 @@ public class AcornManagement implements Management { public void create() throws DatabaseException { db.initFolder(properties); if (!exist()) - throw new DatabaseException("Failed to create ProCore database. folder=" + db.getFolder()); + throw new DatabaseException("Failed to create Acorn database. folder=" + db.getFolder()); } @Override 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 2796e3e02..774b60554 100644 --- a/bundles/org.simantics.acorn/src/org/simantics/acorn/GraphClientImpl2.java +++ b/bundles/org.simantics.acorn/src/org/simantics/acorn/GraphClientImpl2.java @@ -140,7 +140,8 @@ public class GraphClientImpl2 implements Database.Session { } public void makeSnapshot(boolean force) throws IOException { - clusters.makeSnapshot(locator, force); + if (safeToMakeSnapshot) + clusters.makeSnapshot(locator, force); } public T clone(ClusterUID uid, ClusterCreator creator) throws DatabaseException { @@ -166,6 +167,8 @@ public class GraphClientImpl2 implements Database.Session { private boolean closed = false; private boolean isClosing = false; + // Add check to make sure if it safe to make snapshot (used with cancel which is not yet supported and may cause corrupted head.state writing) + private boolean safeToMakeSnapshot = true; @Override public void close() throws ProCoreException { @@ -173,7 +176,7 @@ public class GraphClientImpl2 implements Database.Session { if(!closed && !isClosing) { isClosing = true; try { - makeSnapshot(true); + makeSnapshot(true); mainProgram.close(); clusters.shutdown(); @@ -228,15 +231,17 @@ public class GraphClientImpl2 implements Database.Session { public long cancelCommit(long transactionId, long changeSetId, byte[] metadata, OnChangeSetUpdate onChangeSetUpdate) throws ProCoreException { - System.err.println("GraphClientImpl2.cancelCommit() called!! this is experimental and might cause havoc!"); - try { - undo(new long[] {changeSetId}, onChangeSetUpdate); - } catch (SDBException e) { - e.printStackTrace(); - throw new ProCoreException(e); - } - clusters.state.headChangeSetId++; - return clusters.state.headChangeSetId; + safeToMakeSnapshot = false; + throw new UnsupportedOperationException("org.simantics.acorn.GraphClientImpl2.cancelCommit() is not supported operation! Closing down to prevent further havoc"); +// System.err.println("GraphClientImpl2.cancelCommit() called!! this is experimental and might cause havoc!"); +// try { +// undo(new long[] {changeSetId}, onChangeSetUpdate); +// } catch (SDBException e) { +// e.printStackTrace(); +// throw new ProCoreException(e); +// } +// clusters.state.headChangeSetId++; +// return clusters.state.headChangeSetId; } @Override diff --git a/bundles/org.simantics.acorn/src/org/simantics/acorn/internal/AcornDatabase.java b/bundles/org.simantics.acorn/src/org/simantics/acorn/internal/AcornDatabase.java index 63c73dd63..be505c603 100644 --- a/bundles/org.simantics.acorn/src/org/simantics/acorn/internal/AcornDatabase.java +++ b/bundles/org.simantics.acorn/src/org/simantics/acorn/internal/AcornDatabase.java @@ -2,6 +2,8 @@ package org.simantics.acorn.internal; import java.io.File; import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.channels.FileLock; import java.nio.file.DirectoryStream; import java.nio.file.FileVisitOption; import java.nio.file.FileVisitResult; @@ -28,6 +30,12 @@ public class AcornDatabase implements Database { private DatabaseUserAgent userAgent; + private RandomAccessFile raLockFile; + + private FileLock lock; + + private boolean isRunning; + public AcornDatabase(Path folder) { this.folder = folder; } @@ -93,23 +101,49 @@ public class AcornDatabase implements Database { @Override public void deleteFiles() throws ProCoreException { - // TODO: somehow check that the acorn client is not active. deleteTree(folder); } @Override public void start() throws ProCoreException { + Path lockFile = folder.resolve("lock"); + try { + if (!Files.exists(lockFile)) + Files.createFile(lockFile); + + raLockFile = new RandomAccessFile(lockFile.toFile(), "rw"); + lock = raLockFile.getChannel().tryLock(); + if (lock == null) { + throw new ProCoreException("The database in folder " + folder.toAbsolutePath() + " is already in use!"); + } + + isRunning = true; + + } catch (IOException e) { + e.printStackTrace(); + } } @Override public boolean isRunning() throws ProCoreException { - return true; + return isRunning; } @Override public boolean tryToStop() throws ProCoreException { + try { + lock.release(); + raLockFile.close(); + + Files.deleteIfExists(folder.resolve("lock")); + + isRunning = false; + + } catch (IOException e) { + e.printStackTrace(); + } + return true; -// throw new UnsupportedOperationException(); } @Override @@ -118,7 +152,7 @@ public class AcornDatabase implements Database { @Override public boolean isConnected() throws ProCoreException { - return true; + return isRunning; } @Override