From 07b66baa48848929e9e0be243348e14d184f97b0 Mon Sep 17 00:00:00 2001 From: ilya terskov Date: Fri, 9 Oct 2026 23:32:05 +0700 Subject: [PATCH 1/3] Enable TCP_NODELAY on protocol server child channels to reduce latency --- .../protocols/lib/netty/AbstractConfigurableAsyncServer.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractConfigurableAsyncServer.java b/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractConfigurableAsyncServer.java index 639c418c0ee..a3c68651868 100644 --- a/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractConfigurableAsyncServer.java +++ b/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractConfigurableAsyncServer.java @@ -481,8 +481,9 @@ public String[] getBoundAddresses() { protected void configureBootstrap(ServerBootstrap bootstrap) { super.configureBootstrap(bootstrap); - // enable tcp keep-alives + // enable tcp keep-alives and disable Nagle's algorithm for low latency bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true); + bootstrap.childOption(ChannelOption.TCP_NODELAY, true); } protected abstract ChannelHandlerFactory createFrameHandlerFactory(); From 7c1d3f88e1f281f341d8efa64c9174143764bdaa Mon Sep 17 00:00:00 2001 From: ilya terskov Date: Fri, 9 Oct 2026 16:19:40 +0700 Subject: [PATCH 2/3] fix(protocols): unregister existing mbean before registering on server restart --- .../lib/netty/AbstractConfigurableAsyncServer.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractConfigurableAsyncServer.java b/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractConfigurableAsyncServer.java index a3c68651868..27d263d344c 100644 --- a/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractConfigurableAsyncServer.java +++ b/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractConfigurableAsyncServer.java @@ -130,13 +130,15 @@ public final void setEncryptionFactory(Encryption.Factory encryptionFactory) { } protected void registerMBean() { - try { - mbeanServer.registerMBean(this, new ObjectName(getMBeanName())); + ObjectName objectName = new ObjectName(getMBeanName()); + if (mbeanServer.isRegistered(objectName)) { + mbeanServer.unregisterMBean(objectName); + } + mbeanServer.registerMBean(this, objectName); } catch (Exception e) { throw new RuntimeException("Unable to register mbean", e); } - } protected void unregisterMBean() { From 1c7730a4e00d1d0ef7d8769e54af3ca4ad6336d1 Mon Sep 17 00:00:00 2001 From: ilya terskov Date: Fri, 9 Oct 2026 16:44:29 +0700 Subject: [PATCH 3/3] fix(jmx): eliminate race condition during concurrent Netty server restart in registerMBean --- .../lib/netty/AbstractConfigurableAsyncServer.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractConfigurableAsyncServer.java b/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractConfigurableAsyncServer.java index 27d263d344c..16216f41355 100644 --- a/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractConfigurableAsyncServer.java +++ b/server/protocols/protocols-library/src/main/java/org/apache/james/protocols/lib/netty/AbstractConfigurableAsyncServer.java @@ -132,10 +132,17 @@ public final void setEncryptionFactory(Encryption.Factory encryptionFactory) { protected void registerMBean() { try { ObjectName objectName = new ObjectName(getMBeanName()); - if (mbeanServer.isRegistered(objectName)) { - mbeanServer.unregisterMBean(objectName); + synchronized (mbeanServer) { + if (mbeanServer.isRegistered(objectName)) { + mbeanServer.unregisterMBean(objectName); + } + try { + mbeanServer.registerMBean(this, objectName); + } catch (javax.management.InstanceAlreadyExistsException e) { + mbeanServer.unregisterMBean(objectName); + mbeanServer.registerMBean(this, objectName); + } } - mbeanServer.registerMBean(this, objectName); } catch (Exception e) { throw new RuntimeException("Unable to register mbean", e); }