You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by fr...@apache.org on 2016/08/29 15:51:46 UTC

svn commit: r1758252 - in /jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file: FileReaper.java FileStore.java

Author: frm
Date: Mon Aug 29 15:51:46 2016
New Revision: 1758252

URL: http://svn.apache.org/viewvc?rev=1758252&view=rev
Log:
OAK-4719 - Remove files marked after the failure of the compaction phase

Added:
    jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileReaper.java   (with props)
Modified:
    jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java

Added: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileReaper.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileReaper.java?rev=1758252&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileReaper.java (added)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileReaper.java Mon Aug 29 15:51:46 2016
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jackrabbit.oak.segment.file;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Thread-safe class tracking files to be removed.
+ */
+class FileReaper {
+
+    private static final Logger logger = LoggerFactory.getLogger(FileReaper.class);
+
+    private final Set<File> files = new HashSet<>();
+
+    private final Object lock = new Object();
+
+    /**
+     * Add files to be removed. The same file can be added more than once.
+     * Duplicates are ignored.
+     *
+     * @param files group of files to be removed.
+     */
+    void add(Iterable<File> files) {
+        synchronized (lock) {
+            for (File file : files) {
+                this.files.add(file);
+            }
+        }
+    }
+
+    /**
+     * Reap previously added files.
+     */
+    void reap() {
+        Set<File> reap;
+
+        synchronized (lock) {
+            reap = new HashSet<>(files);
+            files.clear();
+        }
+
+        Set<File> redo = new HashSet<>();
+
+        for (File file : reap) {
+            try {
+                Files.delete(file.toPath());
+                logger.info("Removed file {}", file);
+            } catch (IOException e) {
+                logger.warn(String.format("Unable to remove file %s", file), e);
+                redo.add(file);
+            }
+        }
+
+        if (redo.isEmpty()) {
+            return;
+        }
+
+        add(redo);
+    }
+
+}

Propchange: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileReaper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java?rev=1758252&r1=1758251&r2=1758252&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java Mon Aug 29 15:51:46 2016
@@ -212,7 +212,7 @@ public class FileStore implements Segmen
      * not be removed immediately, because they first need to be closed, and the
      * JVM needs to release the memory mapped file references.
      */
-    private final List<File> pendingRemove = newLinkedList();
+    private final FileReaper fileReaper = new FileReaper();
 
     /**
      * {@code GcListener} listening to this instance's gc progress
@@ -761,24 +761,10 @@ public class FileStore implements Segmen
 
         if (cleanupNeeded.getAndSet(false)) {
             // FIXME OAK-4138: Decouple revision cleanup from the flush thread
-            pendingRemove.addAll(cleanup());
+            fileReaper.add(cleanup());
         }
 
-        // FIXME OAK-4138 Decouple revision cleanup from the flush thread: instead of synchronizing, skip flush if already in progress
-        // remove all obsolete tar generations
-        synchronized (pendingRemove) {
-            Iterator<File> iterator = pendingRemove.iterator();
-            while (iterator.hasNext()) {
-                File file = iterator.next();
-                log.debug("TarMK GC: Attempting to remove old file {}", file);
-                if (!file.exists() || file.delete()) {
-                    log.debug("TarMK GC: Removed old file {}", file);
-                    iterator.remove();
-                } else {
-                    log.warn("TarMK GC: Failed to remove old file {}. Will retry later.", file);
-                }
-            }
-        }
+        fileReaper.reap();
     }
 
     /**
@@ -1095,11 +1081,11 @@ public class FileStore implements Segmen
                         return generation == newGeneration;
                     }
                 };
-                cleanup(cleanupPredicate,
+                fileReaper.add(cleanup(cleanupPredicate,
                     "gc-count=" + GC_COUNT +
                     ",gc-status=failed" +
                     ",store-generation=" + (newGeneration - 1) +
-                    ",reclaim-predicate=(generation==" + newGeneration + ")");
+                    ",reclaim-predicate=(generation==" + newGeneration + ")"));
 
                 gcListener.compacted(FAILURE, newGeneration);
                 gcListener.info("TarMK GC #{}: compaction failed after {} ({} ms), and {} cycles",