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 ad...@apache.org on 2020/08/11 10:02:53 UTC

svn commit: r1880765 - /jackrabbit/oak/trunk/oak-segment-remote/src/main/java/org/apache/jackrabbit/oak/segment/remote/persistentcache/PersistentDiskCache.java

Author: adulceanu
Date: Tue Aug 11 10:02:52 2020
New Revision: 1880765

URL: http://svn.apache.org/viewvc?rev=1880765&view=rev
Log:
OAK-9170 - Make loading segment disk cache fail safe in case when write operation is interrupted by failure
Contribution by Miroslav Smiljanic

Modified:
    jackrabbit/oak/trunk/oak-segment-remote/src/main/java/org/apache/jackrabbit/oak/segment/remote/persistentcache/PersistentDiskCache.java

Modified: jackrabbit/oak/trunk/oak-segment-remote/src/main/java/org/apache/jackrabbit/oak/segment/remote/persistentcache/PersistentDiskCache.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-remote/src/main/java/org/apache/jackrabbit/oak/segment/remote/persistentcache/PersistentDiskCache.java?rev=1880765&r1=1880764&r2=1880765&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-remote/src/main/java/org/apache/jackrabbit/oak/segment/remote/persistentcache/PersistentDiskCache.java (original)
+++ jackrabbit/oak/trunk/oak-segment-remote/src/main/java/org/apache/jackrabbit/oak/segment/remote/persistentcache/PersistentDiskCache.java Tue Aug 11 10:02:52 2020
@@ -33,8 +33,10 @@ import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.nio.channels.FileChannel;
+import java.nio.file.AtomicMoveNotSupportedException;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
 import java.nio.file.attribute.BasicFileAttributes;
 import java.nio.file.attribute.FileTime;
 import java.util.Comparator;
@@ -131,15 +133,28 @@ public class PersistentDiskCache extends
     public void writeSegment(long msb, long lsb, Buffer buffer) {
         String segmentId = new UUID(msb, lsb).toString();
         File segmentFile = new File(directory, segmentId);
+        File tempSegmentFile = new File(directory, segmentId + System.nanoTime() + ".part");
+
         Buffer bufferCopy = buffer.duplicate();
 
         Runnable task = () -> {
             if (lockSegmentWrite(segmentId)) {
-                try (FileChannel channel = new FileOutputStream(segmentFile).getChannel()) {
+                try (FileChannel channel = new FileOutputStream(tempSegmentFile).getChannel()) {
                     int fileSize = bufferCopy.write(channel);
+                    try {
+                        Files.move(tempSegmentFile.toPath(), segmentFile.toPath(), StandardCopyOption.ATOMIC_MOVE);
+                    } catch (AtomicMoveNotSupportedException e) {
+                        Files.move(tempSegmentFile.toPath(), segmentFile.toPath());
+                    }
                     cacheSize.addAndGet(fileSize);
-                } catch (Throwable t) {
-                    logger.error("Error writing segment {} to cache: {}", segmentId, t);
+                } catch (Exception e) {
+                    logger.error("Error writing segment {} to cache: {}", segmentId, e);
+                    try {
+                        Files.deleteIfExists(segmentFile.toPath());
+                        Files.deleteIfExists(tempSegmentFile.toPath());
+                    } catch (IOException i) {
+                        logger.error("Error while deleting corrupted segment file {}", segmentId, i);
+                    }
                 } finally {
                     unlockSegmentWrite(segmentId);
                 }