summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2018-09-26 16:18:08 +0200
committerGitHub <noreply@github.com>2018-09-26 16:18:08 +0200
commitb4bd563a4c22652437a39d83161f14abbb540f6e (patch)
treea7d2fae084392dea90584aefb69dcf7ebb33bae8
parenta246879bed135a7c5861eab5ad0da85e16e539d7 (diff)
Revert "Revert "Balder/add native fadvise""
-rw-r--r--container-accesslogging/src/main/java/com/yahoo/container/logging/LogFileHandler.java20
-rw-r--r--parent/pom.xml7
-rw-r--r--vespajlib/pom.xml4
-rw-r--r--vespajlib/src/main/java/com/yahoo/io/NativeIO.java87
-rw-r--r--vespajlib/src/test/java/com/yahoo/io/NativeIOTestCase.java34
5 files changed, 148 insertions, 4 deletions
diff --git a/container-accesslogging/src/main/java/com/yahoo/container/logging/LogFileHandler.java b/container-accesslogging/src/main/java/com/yahoo/container/logging/LogFileHandler.java
index d729b092670..9963429bf97 100644
--- a/container-accesslogging/src/main/java/com/yahoo/container/logging/LogFileHandler.java
+++ b/container-accesslogging/src/main/java/com/yahoo/container/logging/LogFileHandler.java
@@ -2,6 +2,7 @@
package com.yahoo.container.logging;
import com.yahoo.container.core.AccessLogConfig;
+import com.yahoo.io.NativeIO;
import com.yahoo.log.LogFileDb;
import java.io.File;
@@ -263,15 +264,28 @@ public class LogFileHandler extends StreamHandler {
numberOfRecords = 0;
lastRotationTime = now;
nextRotationTime = 0; //figure it out later (lazy evaluation)
- if (compressOnRotation && (oldFileName != null)) {
- triggerCompression(oldFileName);
+ if ((oldFileName != null)) {
+ if (compressOnRotation) {
+ triggerCompression(oldFileName);
+ } else {
+ NativeIO nativeIO = new NativeIO();
+ nativeIO.dropFileFromCache(new File(oldFileName));
+ }
}
}
private void triggerCompression(String oldFileName) {
try {
+ String gzippedFileName = oldFileName + ".gz";
Runtime r = Runtime.getRuntime();
- Process p = r.exec(new String[] { "gzip", oldFileName });
+ StringBuilder cmd = new StringBuilder("gzip");
+ cmd.append(" < "). append(oldFileName).append(" > ").append(gzippedFileName);
+ Process p = r.exec(cmd.toString());
+ NativeIO nativeIO = new NativeIO();
+ File oldFile = new File(oldFileName);
+ nativeIO.dropFileFromCache(oldFile); // Drop from cache in case somebody else has a reference to it preventing from dying quickly.
+ oldFile.delete();
+ nativeIO.dropFileFromCache(new File(gzippedFileName));
// Detonator pattern: Think of all the fun we can have if gzip isn't what we
// think it is, if it doesn't return, etc, etc
} catch (IOException e) {
diff --git a/parent/pom.xml b/parent/pom.xml
index 96075974567..a46b86f2725 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -461,7 +461,7 @@
<artifactId>commons-pool</artifactId>
<version>1.5.6</version>
</dependency>
- <!-- Explicitly included to get Zookeeper version 3.4.12,
+ <!-- Explicitly included to get Zookeeper version 3.4.13,
can be excluded if you want the Zookeeper version
used by curator by default
-->
@@ -673,6 +673,11 @@
<artifactId>language-detector</artifactId>
<version>0.6</version>
</dependency>
+ <dependency>
+ <groupId>net.java.dev.jna</groupId>
+ <artifactId>jna</artifactId>
+ <version>4.5.2</version>
+ </dependency>
</dependencies>
</dependencyManagement>
diff --git a/vespajlib/pom.xml b/vespajlib/pom.xml
index 5b9c143a447..741b4b58cc9 100644
--- a/vespajlib/pom.xml
+++ b/vespajlib/pom.xml
@@ -31,6 +31,10 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-exec</artifactId>
</dependency>
+ <dependency>
+ <groupId>net.java.dev.jna</groupId>
+ <artifactId>jna</artifactId>
+ </dependency>
<!-- provided scope -->
diff --git a/vespajlib/src/main/java/com/yahoo/io/NativeIO.java b/vespajlib/src/main/java/com/yahoo/io/NativeIO.java
new file mode 100644
index 00000000000..bee43a8653e
--- /dev/null
+++ b/vespajlib/src/main/java/com/yahoo/io/NativeIO.java
@@ -0,0 +1,87 @@
+package com.yahoo.io;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.util.logging.Logger;
+
+import com.sun.jna.LastErrorException;
+import com.sun.jna.Native;
+import com.sun.jna.Platform;
+
+public class NativeIO {
+ private final Logger logger = Logger.getLogger(getClass().getName());
+ private static final int POSIX_FADV_DONTNEED = 4; // See /usr/include/linux/fadvise.h
+ private static boolean initialized = false;
+ private static Throwable initError = null;
+ static {
+ try {
+ if (Platform.isLinux()) {
+ Native.register(Platform.C_LIBRARY_NAME);
+ initialized = true;
+ }
+ } catch (Throwable throwable) {
+ initError = throwable;
+ }
+ }
+
+ private static final Field fieldFD = getField(FileDescriptor.class, "fd");
+
+
+ private static native int posix_fadvise(int fd, long offset, long len, int flag) throws LastErrorException;
+
+ public NativeIO() {
+ if (!initialized) {
+ logger.warning("native IO not possible due to " + getError().getMessage());
+ }
+ }
+
+ public boolean valid() { return initialized; }
+ public Throwable getError() {
+ if (initError != null) {
+ return initError;
+ } else {
+ return new RuntimeException("Platform is unsúpported. Only supported on linux.");
+ }
+ }
+
+ public void dropFileFromCache(FileDescriptor fd) {
+ if (initialized) {
+ posix_fadvise(getNativeFD(fd), 0, 0, POSIX_FADV_DONTNEED);
+ }
+ }
+
+ public void dropFileFromCache(File file) {
+ try {
+ dropFileFromCache(new FileInputStream(file).getFD());
+ } catch (FileNotFoundException e) {
+ throw new RuntimeException(e);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+
+ private static Field getField(Class<?> clazz, String fieldName) {
+ Field field;
+ try {
+ field = clazz.getDeclaredField(fieldName);
+ } catch (NoSuchFieldException e) {
+ throw new RuntimeException(e);
+ }
+ field.setAccessible(true);
+ return field;
+ }
+
+ private static int getNativeFD(FileDescriptor fd) {
+ try {
+ return fieldFD.getInt(fd);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+}
diff --git a/vespajlib/src/test/java/com/yahoo/io/NativeIOTestCase.java b/vespajlib/src/test/java/com/yahoo/io/NativeIOTestCase.java
new file mode 100644
index 00000000000..ecd38056a19
--- /dev/null
+++ b/vespajlib/src/test/java/com/yahoo/io/NativeIOTestCase.java
@@ -0,0 +1,34 @@
+package com.yahoo.io;
+
+import com.sun.jna.Platform;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+
+public class NativeIOTestCase {
+
+ @Test
+ public void requireThatDropFileFromCacheDoesNotThrow() throws IOException {
+ File testFile = new File("testfile");
+ FileOutputStream output = new FileOutputStream(testFile);
+ output.write('t');
+ output.flush();
+ output.close();
+ NativeIO nativeIO = new NativeIO();
+ if (Platform.isLinux()) {
+ assertTrue(nativeIO.valid());
+ } else {
+ assertFalse(nativeIO.valid());
+ assertEquals("Platform is unsúpported. Only supported on linux.", nativeIO.getError().getMessage());
+ }
+ nativeIO.dropFileFromCache(output.getFD());
+ nativeIO.dropFileFromCache(testFile);
+ testFile.delete();
+ }
+}