package org.jgroups.tests; import org.jgroups.*; import org.jgroups.conf.ClassConfigurator; import org.jgroups.protocols.SenderSendsBundler; import org.jgroups.protocols.TP; import org.jgroups.util.MessageBatch; import org.jgroups.util.Util; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import java.util.ArrayList; import java.util.List; import static org.jgroups.Message.Flag.OOB; /** * Tests unnecessary resizing of headers (https://issues.jboss.org/browse/JGRP-2120) * @author Bela Ban * @since 4.0 */ @Test(groups=Global.FUNCTIONAL) public class HeadersResizeTest { protected JChannel a,b; protected static final short transport_id; static { transport_id=ClassConfigurator.getProtocolId(TP.class); } @BeforeMethod protected void setup() throws Exception { a=new JChannel(Util.getTestStack()).name("A").connect(HeadersResizeTest.class.getSimpleName()); b=new JChannel(Util.getTestStack()).name("B").connect(HeadersResizeTest.class.getSimpleName()); Util.waitUntilAllChannelsHaveSameView(10000, 500, a,b); } @AfterMethod protected void tearDown() {Util.close(b, a);} public void testResizing() throws Exception { BatchingBundler bundler=new BatchingBundler(); TP transport=a.getProtocolStack().getTransport(); bundler.init(transport); a.getProtocolStack().getTransport().setBundler(bundler); MyReceiver receiver=new MyReceiver(); b.setReceiver(receiver); Address dest=b.getAddress(); bundler.hold(); for(int i=1; i <= 5; i++) { // these 5 messages will be queued by the bundler Message msg=new Message(dest, i).setFlag(OOB, Message.Flag.DONT_BUNDLE); a.send(msg); } bundler.release(); // sends all bundled messages as a batch for(int i=0; i < 10; i++) { if(receiver.num_msgs >= 5) break; Util.sleep(200); } System.out.printf("Number of transport headers: %d\n", receiver.num_transport_headers); assert receiver.num_transport_headers == 0; } protected static class BatchingBundler extends SenderSendsBundler { protected boolean queue; protected final List<Message> list=new ArrayList<>(16); public synchronized void send(Message msg) throws Exception { if(!queue) super.send(msg); else list.add(msg); } protected synchronized void hold() { // messages will not be sent from now on (they're queued) queue=true; } protected synchronized void release() { // the next send() will send all queued messages for(Message msg: list) addMessage(msg, msg.size()); list.clear(); queue=false; sendBundledMessages(); } } protected static class MyReceiver extends ReceiverAdapter { protected int num_msgs, num_transport_headers; public void receive(Message msg) { System.out.printf("received message from %s: %s\n", msg.src(), msg.getObject()); num_msgs++; Header hdr=msg.getHeader(transport_id); if(hdr != null) num_transport_headers++; } public void receive(MessageBatch batch) { System.out.printf("received batch of %d msgs\n", batch.size()); } } }