You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ni...@apache.org on 2022/03/23 14:40:05 UTC

[ignite] 01/01: IGNITE-16730 Eliminate FileLock usage for writing marshaller mapping

This is an automated email from the ASF dual-hosted git repository.

nizhikov pushed a commit to branch IGNITE-16730
in repository https://gitbox.apache.org/repos/asf/ignite.git

commit bf77177e213f62ece065926b50d4cda43e68a65b
Author: Nikolay <ni...@apache.org>
AuthorDate: Wed Mar 23 17:39:11 2022 +0300

    IGNITE-16730 Eliminate FileLock usage for writing marshaller mapping
---
 .../internal/MarshallerMappingFileStore.java       | 90 ++++++++--------------
 1 file changed, 30 insertions(+), 60 deletions(-)

diff --git a/modules/core/src/main/java/org/apache/ignite/internal/MarshallerMappingFileStore.java b/modules/core/src/main/java/org/apache/ignite/internal/MarshallerMappingFileStore.java
index 605ca31..aff4d11 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/MarshallerMappingFileStore.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/MarshallerMappingFileStore.java
@@ -25,9 +25,6 @@ import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
 import java.io.Writer;
-import java.nio.channels.FileChannel;
-import java.nio.channels.FileLock;
-import java.nio.channels.OverlappingFileLockException;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.util.concurrent.ThreadLocalRandom;
@@ -39,6 +36,9 @@ import org.apache.ignite.internal.util.IgniteUtils;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.marshaller.MarshallerContext;
 
+import static java.nio.file.StandardCopyOption.ATOMIC_MOVE;
+import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
+
 /**
  * File-based persistence provider for {@link MarshallerContextImpl}.
  *
@@ -91,33 +91,26 @@ final class MarshallerMappingFileStore {
     void writeMapping(byte platformId, int typeId, String typeName) {
         String fileName = getFileName(platformId, typeId);
 
+        File tmpFile = new File(mappingDir, fileName + "." + ThreadLocalRandom.current().nextInt() + ".tmp");
+        File file = new File(mappingDir, fileName);
+
         Lock lock = fileLock(fileName);
 
         lock.lock();
 
         try {
-            File file = new File(mappingDir, fileName);
+            try (FileOutputStream out = new FileOutputStream(tmpFile);
+                 Writer writer = new OutputStreamWriter(out, StandardCharsets.UTF_8)) {
+                writer.write(typeName);
 
-            try (FileOutputStream out = new FileOutputStream(file)) {
-                try (Writer writer = new OutputStreamWriter(out, StandardCharsets.UTF_8)) {
-                    try (FileLock ignored = fileLock(out.getChannel(), false)) {
-                        writer.write(typeName);
-
-                        writer.flush();
-                    }
-                }
-            }
-            catch (IOException e) {
-                U.error(log, "Failed to write class name to file [platformId=" + platformId + "id=" + typeId +
-                        ", clsName=" + typeName + ", file=" + file.getAbsolutePath() + ']', e);
-            }
-            catch (OverlappingFileLockException ignored) {
-                if (log.isDebugEnabled())
-                    log.debug("File already locked (will ignore): " + file.getAbsolutePath());
-            }
-            catch (IgniteInterruptedCheckedException e) {
-                U.error(log, "Interrupted while waiting for acquiring file lock: " + file, e);
+                writer.flush();
             }
+
+            Files.move(tmpFile.toPath(), file.toPath(), REPLACE_EXISTING, ATOMIC_MOVE);
+        }
+        catch (IOException e) {
+            U.error(log, "Failed to write class name to file [platformId=" + platformId + "id=" + typeId +
+                ", clsName=" + typeName + ", file=" + tmpFile.getAbsolutePath() + ']', e);
         }
         finally {
             lock.unlock();
@@ -140,23 +133,20 @@ final class MarshallerMappingFileStore {
             long time = 0;
 
             while (true) {
-                try (FileInputStream in = new FileInputStream(file)) {
-                    try (BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) {
-                        try (FileLock ignored = fileLock(in.getChannel(), true)) {
-                            if (file.length() > 0)
-                                return reader.readLine();
-
-                            if (rnd == null)
-                                rnd = ThreadLocalRandom.current();
-
-                            if (time == 0)
-                                time = System.nanoTime();
-                            else if (U.millisSinceNanos(time) >= FILE_LOCK_TIMEOUT_MS)
-                                return null;
-
-                            U.sleep(rnd.nextLong(50));
-                        }
-                    }
+                try (FileInputStream in = new FileInputStream(file);
+                     BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) {
+                    if (file.length() > 0)
+                        return reader.readLine();
+
+                    if (rnd == null)
+                        rnd = ThreadLocalRandom.current();
+
+                    if (time == 0)
+                        time = System.nanoTime();
+                    else if (U.millisSinceNanos(time) >= FILE_LOCK_TIMEOUT_MS)
+                        return null;
+
+                    U.sleep(rnd.nextLong(50));
                 }
                 catch (IOException ignored) {
                     return null;
@@ -321,24 +311,4 @@ final class MarshallerMappingFileStore {
     private static Lock fileLock(String fileName) {
         return fileLock.getLock(fileName.hashCode());
     }
-
-    /**
-     * @param ch File channel.
-     * @param shared Shared.
-     */
-    private static FileLock fileLock(
-            FileChannel ch,
-            boolean shared
-    ) throws IOException, IgniteInterruptedCheckedException {
-        ThreadLocalRandom rnd = ThreadLocalRandom.current();
-
-        while (true) {
-            FileLock fileLock = ch.tryLock(0L, Long.MAX_VALUE, shared);
-
-            if (fileLock != null)
-                return fileLock;
-
-            U.sleep(rnd.nextLong(50));
-        }
-    }
 }