This is an automated email from the ASF dual-hosted git repository. rmaucher pushed a commit to branch 9.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 9bc3b9c629f8d19744585c13f0f242a05baf8306 Author: opencode <[email protected]> AuthorDate: Sun Oct 11 16:30:17 2026 +0200 Apply the configured UDP buffer sizes of a cluster sender AbstractSender.transferProperties() copied every configured property but the UDP socket buffer sizes onto the senders it creates, so a configured udpRxBufSize or udpTxBufSize on the cluster channel Sender element was dropped twice over: once when the pool created its senders and again when a sender created its per-member senders. NioSender.configureSocket() therefore always sized the datagram socket from the field defaults and the configured values had no effect at all. Transfer both values along with the transmit and receive buffer sizes of the TCP path, which were already transferred. The default configuration is unaffected, as the transferred defaults are the same values the fields were initialised with. Add TestAbstractSender, which sets a distinct value for each property a sender transfers and checks that all of them survive a direct transfer as well as the hand-over from a pool to a newly created sender. --- .../catalina/tribes/transport/AbstractSender.java | 2 + .../tribes/transport/TestAbstractSender.java | 121 +++++++++++++++++++++ webapps/docs/changelog.xml | 9 ++ 3 files changed, 132 insertions(+) diff --git a/java/org/apache/catalina/tribes/transport/AbstractSender.java b/java/org/apache/catalina/tribes/transport/AbstractSender.java index 49ff819ca9..bbe3dbcbab 100644 --- a/java/org/apache/catalina/tribes/transport/AbstractSender.java +++ b/java/org/apache/catalina/tribes/transport/AbstractSender.java @@ -86,6 +86,8 @@ public abstract class AbstractSender implements DataSender { public static void transferProperties(AbstractSender from, AbstractSender to) { to.rxBufSize = from.rxBufSize; to.txBufSize = from.txBufSize; + to.udpRxBufSize = from.udpRxBufSize; + to.udpTxBufSize = from.udpTxBufSize; to.directBuffer = from.directBuffer; to.keepAliveCount = from.keepAliveCount; to.keepAliveTime = from.keepAliveTime; diff --git a/test/org/apache/catalina/tribes/transport/TestAbstractSender.java b/test/org/apache/catalina/tribes/transport/TestAbstractSender.java new file mode 100644 index 0000000000..19b6fe952f --- /dev/null +++ b/test/org/apache/catalina/tribes/transport/TestAbstractSender.java @@ -0,0 +1,121 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.catalina.tribes.transport; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Assume; +import org.junit.Before; +import org.junit.Test; + +import org.apache.catalina.tribes.group.TribesSslContext; +import org.apache.catalina.tribes.membership.MemberImpl; +import org.apache.catalina.tribes.transport.nio.NioSender; +import org.apache.catalina.tribes.transport.nio.PooledParallelSender; + +public class TestAbstractSender { + + private TribesSslContext sslContext; + + @Before + public void setUp() { + try { + sslContext = new TribesSslContext("tribes-test", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "SHA256", "TLSv1.3"); + } catch (Exception e) { + Assume.assumeNoException(e); + } + } + + @After + public void tearDown() throws Exception { + if (sslContext != null) { + sslContext.close(); + } + } + + @Test + public void testTransferProperties() throws Exception { + AbstractSender source = new NioSender(); + setValues(source); + AbstractSender target = new NioSender(); + AbstractSender.transferProperties(source, target); + assertTransferred(source, target); + } + + /* + * A pooled sender hands its own configuration over to every sender it creates, so a configured value has to survive + * that hand-over. The UDP buffer sizes are only used once a sender connects, which makes them easy to overlook. The + * new sender is never connected and its selector is released by the cleaner registered by ParallelNioSender. + */ + @Test + public void testTransferPropertiesForPooledSender() throws Exception { + PooledParallelSender pool = new PooledParallelSender(); + setValues(pool); + assertTransferred(pool, (AbstractSender) pool.getNewDataSender()); + } + + private void setValues(AbstractSender sender) throws Exception { + sender.setDestination(new MemberImpl("localhost", 4444, 4000)); + sender.setRxBufSize(11111); + sender.setTxBufSize(22222); + sender.setUdpRxBufSize(33333); + sender.setUdpTxBufSize(44444); + sender.setDirectBuffer(true); + sender.setKeepAliveCount(55); + sender.setKeepAliveTime(66666); + sender.setTimeout(77777); + sender.setMaxRetryAttempts(3); + sender.setTcpNoDelay(false); + sender.setSoKeepAlive(true); + sender.setOoBInline(false); + sender.setSoReuseAddress(false); + sender.setSoLingerOn(true); + sender.setSoLingerTime(9); + sender.setSoTrafficClass(0x10); + sender.setThrowOnFailedAck(false); + sender.setUdpBased(true); + sender.setUdpPort(5000); + sender.setSslContext(sslContext); + } + + private void assertTransferred(AbstractSender expected, AbstractSender actual) { + Assert.assertEquals("destination", expected.getDestination(), actual.getDestination()); + Assert.assertEquals("address", expected.getAddress(), actual.getAddress()); + Assert.assertEquals("port", expected.getPort(), actual.getPort()); + Assert.assertEquals("udpPort", expected.getUdpPort(), actual.getUdpPort()); + Assert.assertEquals("rxBufSize", expected.getRxBufSize(), actual.getRxBufSize()); + Assert.assertEquals("txBufSize", expected.getTxBufSize(), actual.getTxBufSize()); + Assert.assertEquals("udpRxBufSize", expected.getUdpRxBufSize(), actual.getUdpRxBufSize()); + Assert.assertEquals("udpTxBufSize", expected.getUdpTxBufSize(), actual.getUdpTxBufSize()); + Assert.assertEquals("directBuffer", expected.getDirectBuffer(), actual.getDirectBuffer()); + Assert.assertEquals("keepAliveCount", expected.getKeepAliveCount(), actual.getKeepAliveCount()); + Assert.assertEquals("keepAliveTime", expected.getKeepAliveTime(), actual.getKeepAliveTime()); + Assert.assertEquals("timeout", expected.getTimeout(), actual.getTimeout()); + Assert.assertEquals("maxRetryAttempts", expected.getMaxRetryAttempts(), actual.getMaxRetryAttempts()); + Assert.assertEquals("tcpNoDelay", expected.getTcpNoDelay(), actual.getTcpNoDelay()); + Assert.assertEquals("soKeepAlive", expected.getSoKeepAlive(), actual.getSoKeepAlive()); + Assert.assertEquals("ooBInline", expected.getOoBInline(), actual.getOoBInline()); + Assert.assertEquals("soReuseAddress", expected.getSoReuseAddress(), actual.getSoReuseAddress()); + Assert.assertEquals("soLingerOn", expected.getSoLingerOn(), actual.getSoLingerOn()); + Assert.assertEquals("soLingerTime", expected.getSoLingerTime(), actual.getSoLingerTime()); + Assert.assertEquals("soTrafficClass", expected.getSoTrafficClass(), actual.getSoTrafficClass()); + Assert.assertEquals("throwOnFailedAck", expected.getThrowOnFailedAck(), actual.getThrowOnFailedAck()); + Assert.assertEquals("udpBased", expected.isUdpBased(), actual.isUdpBased()); + Assert.assertEquals("sslContext", expected.getSslContext(), actual.getSslContext()); + } +} diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index ace6447e42..4af9cab2f0 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -2529,6 +2529,15 @@ session operation and the state transfer of joining members for the duration of that work. (remm) </fix> + <fix> + The <code>udpRxBufSize</code> and <code>udpTxBufSize</code> configured + on the cluster channel <code>Sender</code> now take effect for messages + sent using UDP. These two properties were missing from the properties + transferred from the configured sender to the pooled senders and on to + the per-member senders those create, so the datagram socket was always + configured with the default buffer sizes and the configured values were + silently ignored. (remm) + </fix> </changelog> </subsection> <subsection name="Other"> --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
