Repository: real-logic/aeron
Issue: ReceiverTest setUp() method throws exception

OS (uname -a): Linux 3.5.0-51-generic #77~precise1-Ubuntu SMP Thu Jun 5 00:48:28 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

Thanks for open sourcing this library.  I hope to learn a lot about high performance messaging from it.

I noticed that the ReceiverTest tearDown() method was throwing NPEs when closing the receiveChannelEndpoint so I wrapped the creation of the ReceiveChannelEndpoint in the ReceiverTest's setUp() method with a try/catch that printed the exception and I got this:

Exception: java.lang.IllegalStateException: Failed to set SO_RCVBUF: attempted=131072, actual=131071

Looks like UdpChannelTransport's constructor is throwing the exception.

% sysctl net | grep 131071
net.core.rmem_max = 131071
net.core.wmem_max = 131071

Looks like there's a hard limit we're hitting up against.

Thanks!


Changed files:
aeron-driver/src/main/java/uk/co/real_logic/aeron/driver/MediaDriver.java
aeron-driver/src/main/java/uk/co/real_logic/aeron/driver/media/UdpChannelTransport.java

diff --git a/aeron-driver/src/main/java/uk/co/real_logic/aeron/driver/MediaDriver.java b/aeron-driver/src/main/java/uk/co/real_logic/aeron/driver/MediaDriver.java
index e3430f374..dfd794552 100644
--- a/aeron-driver/src/main/java/uk/co/real_logic/aeron/driver/MediaDriver.java
+++ b/aeron-driver/src/main/java/uk/co/real_logic/aeron/driver/MediaDriver.java
@@ -35,6 +35,11 @@ import uk.co.real_logic.agrona.concurrent.ringbuffer.RingBuffer;
 import java.io.File;
 import java.nio.ByteBuffer;
 import java.nio.MappedByteBuffer;
+
+import java.nio.channels.DatagramChannel;
+import java.net.StandardSocketOptions;
+import java.io.IOException;
+
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
@@ -103,6 +108,8 @@ public final class MediaDriver implements AutoCloseable
 
         ensureDirectoriesAreRecreated();
 
+        warnOnInsufficentSocketBuffers();
+
         ctx.unicastSenderFlowControl(Configuration::unicastFlowControlStrategy)
             .multicastSenderFlowControl(Configuration::multicastFlowControlStrategy)
             .conductorTimerWheel(Configuration.newConductorTimerWheel())
@@ -247,6 +254,38 @@ public final class MediaDriver implements AutoCloseable
         return this;
     }
 
+    private void warnOnInsufficentSocketBuffers()
+    {
+        try (DatagramChannel probe = DatagramChannel.open())
+        {
+
+            probe.setOption(StandardSocketOptions.SO_SNDBUF, Integer.MAX_VALUE);
+            final int maxSoSndbuf = probe.getOption(StandardSocketOptions.SO_SNDBUF);
+
+            if (maxSoSndbuf < Configuration.SOCKET_SNDBUF_LENGTH)
+            {
+                System.err.println(
+                        String.format("WARNING: Could not get desired SO_SNDBUF: attempted=%d, actual=%d",
+                            Configuration.SOCKET_SNDBUF_LENGTH, maxSoSndbuf));
+            }
+
+            probe.setOption(StandardSocketOptions.SO_RCVBUF, Integer.MAX_VALUE);
+            final int maxSoRcvbuf = probe.getOption(StandardSocketOptions.SO_RCVBUF);
+
+            if (maxSoRcvbuf < Configuration.SOCKET_RCVBUF_LENGTH)
+            {
+                System.err.println(
+                        String.format("WARNING: Could not get desired SO_RCVBUF: attempted=%d, actual=%d",
+                            Configuration.SOCKET_RCVBUF_LENGTH, maxSoRcvbuf));
+            }
+        }
+        catch (final IOException ex)
+        {
+            throw new RuntimeException(
+                String.format("probe socket: %s", ex.toString()), ex);
+        }
+    }
+
     private void ensureDirectoriesAreRecreated()
     {
         final BiConsumer<String, String> callback =
diff --git a/aeron-driver/src/main/java/uk/co/real_logic/aeron/driver/media/UdpChannelTransport.java b/aeron-driver/src/main/java/uk/co/real_logic/aeron/driver/media/UdpChannelTransport.java
index 045ae88a8..0b8d56182 100644
--- a/aeron-driver/src/main/java/uk/co/real_logic/aeron/driver/media/UdpChannelTransport.java
+++ b/aeron-driver/src/main/java/uk/co/real_logic/aeron/driver/media/UdpChannelTransport.java
@@ -78,25 +78,11 @@ public abstract class UdpChannelTransport implements AutoCloseable
             if (0 != Configuration.SOCKET_SNDBUF_LENGTH)
             {
                 datagramChannel.setOption(StandardSocketOptions.SO_SNDBUF, Configuration.SOCKET_SNDBUF_LENGTH);
-                final int soSndbuf = datagramChannel.getOption(StandardSocketOptions.SO_SNDBUF);
-
-                if (soSndbuf != Configuration.SOCKET_SNDBUF_LENGTH)
-                {
-                    throw new IllegalStateException(String.format(
-                        "Failed to set SO_SNDBUF: attempted=%d, actual=%d", Configuration.SOCKET_SNDBUF_LENGTH, soSndbuf));
-                }
             }
 
             if (0 != Configuration.SOCKET_RCVBUF_LENGTH)
             {
                 datagramChannel.setOption(StandardSocketOptions.SO_RCVBUF, Configuration.SOCKET_RCVBUF_LENGTH);
-                final int soRcvbuf = datagramChannel.getOption(StandardSocketOptions.SO_RCVBUF);
-
-                if (soRcvbuf != Configuration.SOCKET_RCVBUF_LENGTH)
-                {
-                    throw new IllegalStateException(String.format(
-                        "Failed to set SO_RCVBUF: attempted=%d, actual=%d", Configuration.SOCKET_RCVBUF_LENGTH, soRcvbuf));
-                }
             }
 
             datagramChannel.configureBlocking(false);