From f3722ed979e9dced32ff2f058cf4b2671adeeabc Mon Sep 17 00:00:00 2001
From: Jeffrey Phillips Freeman <jeffrey.freeman@syncleus.com>
Date: Mon, 4 Sep 2017 20:28:10 -0400
Subject: [PATCH] feat: added rolling graph backups.

---
 .gitignore                                    |  1 +
 .../graphdb/GraphDbAetherMudStorage.java      | 43 ++++++++++++++++++-
 2 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/.gitignore b/.gitignore
index 2746325d..03fc2c78 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,3 +12,4 @@ creeperDb*
 *.log
 release.properties
 aethermud-graph.json
+aethermud-graph.json*
diff --git a/src/main/java/com/syncleus/aethermud/storage/graphdb/GraphDbAetherMudStorage.java b/src/main/java/com/syncleus/aethermud/storage/graphdb/GraphDbAetherMudStorage.java
index 2602ead4..92a97b85 100644
--- a/src/main/java/com/syncleus/aethermud/storage/graphdb/GraphDbAetherMudStorage.java
+++ b/src/main/java/com/syncleus/aethermud/storage/graphdb/GraphDbAetherMudStorage.java
@@ -29,15 +29,23 @@ import org.apache.log4j.Logger;
 import org.apache.tinkerpop.gremlin.structure.Graph;
 import org.apache.tinkerpop.gremlin.structure.io.IoCore;
 
+import java.io.File;
+import java.io.FileFilter;
 import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.*;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReadWriteLock;
 import java.util.stream.Collectors;
 
+import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
+
 //TODO : multiple instances of this class could create conflicts in the DB
 public class GraphDbAetherMudStorage extends AbstractIdleService implements AetherMudStorage {
+    private static final int MAX_BACKUPS = 5;
     private static final Logger LOGGER = Logger.getLogger(GraphDbAetherMudStorage.class);
     private final WrappedFramedGraph<Graph> framedGraph;
     private final String graphDbFile;
@@ -80,7 +88,40 @@ public class GraphDbAetherMudStorage extends AbstractIdleService implements Aeth
 
     }
 
-    public void persist() {
+    public synchronized void persist() {
+        try {
+            Path defaultFilePath = Paths.get(this.graphDbFile);
+            if( Files.exists(defaultFilePath) )
+                Files.move(defaultFilePath, Paths.get(this.graphDbFile + new Date().getTime()), REPLACE_EXISTING);
+        } catch (IOException e) {
+            //do nothing, it probably doesnt exist
+        }
+
+        //remove all but the last 20 backedup files
+        NavigableSet<File> orderedFiles = new TreeSet<>(new Comparator<File>() {
+            @Override
+            public int compare(File file, File t1) {
+                if( file.lastModified() > t1.lastModified() )
+                    return 1;
+                else if( file.lastModified() < t1.lastModified() )
+                    return -1;
+                else
+                    return 0;
+            }
+        });
+        File folder = new File(".");
+        orderedFiles.addAll(Arrays.asList(folder.listFiles(new FileFilter() {
+            @Override
+            public boolean accept(File file) {
+                return file.getName().contains(graphDbFile);
+            }
+        })));
+        while(orderedFiles.size() > MAX_BACKUPS) {
+            File currentFile = orderedFiles.first();
+            orderedFiles.remove(currentFile);
+            currentFile.delete();
+        }
+
         try {
             this.framedGraph.getBaseGraph().io(IoCore.graphson()).writeGraph(this.graphDbFile);
         } catch (IOException e) {
-- 
GitLab