]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.acorn/src/org/simantics/acorn/backup/AcornBackupProvider.java
Fixed Acorn deadlock during snapshotting
[simantics/platform.git] / bundles / org.simantics.acorn / src / org / simantics / acorn / backup / AcornBackupProvider.java
index 5ea0799d82fd116d2c9467a24a81a47cfeb1e6ac..a5aa4f2ef6bcfc7b8d19c70d2a0d7effeca9c4ab 100644 (file)
@@ -16,7 +16,9 @@ import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
+import org.simantics.acorn.AcornSessionManagerImpl;
 import org.simantics.acorn.GraphClientImpl2;
+import org.simantics.acorn.exception.IllegalAcornStateException;
 import org.simantics.backup.BackupException;
 import org.simantics.backup.IBackupProvider;
 import org.simantics.db.server.ProCoreException;
@@ -32,18 +34,22 @@ public class AcornBackupProvider implements IBackupProvider {
     private static final String IDENTIFIER = "AcornBackupProvider";
     private long trId = -1;
     private final Semaphore lock = new Semaphore(1);
+    private final GraphClientImpl2 client;
 
-    private static Path getAcornMetadataFile(Path dbFolder) {
+    public AcornBackupProvider() {
+        this.client = AcornSessionManagerImpl.getInstance().getClient();
+    }
+
+    public static Path getAcornMetadataFile(Path dbFolder) {
         return dbFolder.getParent().resolve(IDENTIFIER);
     }
-    
+
     @Override
     public void lock() throws BackupException {
         try {
             if (trId != -1)
                 throw new IllegalStateException(this + " backup provider is already locked");
-            trId = GraphClientImpl2.getInstance().askWriteTransaction(-1)
-                    .getTransactionId();
+            trId = client.askWriteTransaction(-1).getTransactionId();
         } catch (ProCoreException e) {
             e.printStackTrace();
         }
@@ -54,32 +60,15 @@ public class AcornBackupProvider implements IBackupProvider {
         boolean releaseLock = true;
         try {
             lock.acquire();
-
-            GraphClientImpl2 client = GraphClientImpl2.getInstance();
-            client.makeSnapshot(true);
-
-            Path dbDir = client.getDbFolder();
-            int newestFolder = client.clusters.mainState.headDir - 1;
-            int latestFolder = -2;
-            Path AcornMetadataFile = getAcornMetadataFile(dbDir);
-            if (Files.exists(AcornMetadataFile)) {
-                try (BufferedReader br = Files.newBufferedReader(AcornMetadataFile)) {
-                    latestFolder = Integer.parseInt( br.readLine() );
-                }
-            }
-
-            AcornBackupRunnable r = new AcornBackupRunnable(
-                    lock, targetPath, revision, dbDir, latestFolder, newestFolder);
-            new Thread(r, "Acorn backup thread").start();
-
-             releaseLock = false;
-             return r;
+            Future<BackupException> r = client.getBackupRunnable(lock, targetPath, revision);
+            releaseLock = false;
+            return r;
         } catch (InterruptedException e) {
             releaseLock = false;
             throw new BackupException("Failed to lock Acorn for backup.", e);
         } catch (NumberFormatException e) {
             throw new BackupException("Failed to read Acorn head state file.", e);
-        } catch (IOException e) {
+        } catch (IllegalAcornStateException | IOException e) {
             throw new BackupException("I/O problem during Acorn backup.", e);
         } finally {
             if (releaseLock)
@@ -92,7 +81,7 @@ public class AcornBackupProvider implements IBackupProvider {
         try {
             if (trId == -1)
                 throw new BackupException(this + " backup provider is not locked");
-            GraphClientImpl2.getInstance().endTransaction(trId);
+            client.endTransaction(trId);
             trId = -1;
         } catch (ProCoreException e) {
             throw new BackupException(e);
@@ -105,7 +94,7 @@ public class AcornBackupProvider implements IBackupProvider {
             // 1. Resolve initial backup restore target.
             // This can be DB directory directly or a temporary directory that
             // will replace the DB directory.
-            Path dbRoot = GraphClientImpl2.getInstance().getDbFolder();
+            Path dbRoot = client.getDbFolder();
             Path restorePath = dbRoot;
             if (!Files.exists(dbRoot, LinkOption.NOFOLLOW_LINKS)) {
                 Files.createDirectories(dbRoot);
@@ -122,7 +111,7 @@ public class AcornBackupProvider implements IBackupProvider {
             if (dbRoot != restorePath) {
                 FileUtils.deleteAll(dbRoot.toFile());
                 Files.move(restorePath, dbRoot);
-            } 
+            }
         } catch (IOException e) {
             e.printStackTrace();
         }
@@ -173,7 +162,7 @@ public class AcornBackupProvider implements IBackupProvider {
         }
     }
 
-    private static class AcornBackupRunnable implements Runnable, Future<BackupException> {
+    public static class AcornBackupRunnable implements Runnable, Future<BackupException> {
 
         private final Semaphore lock;
         private final Path targetPath;