INT-3433 Delay Failed IOs
JIRA: https://jira.spring.io/browse/INT-3433` If a read fails due to insufficient threads, delay the read for (default 100ms) - do not re-enable OP_READ until that time has elapsed. Avoids spinning the CPU. INT-3433 More Polishing If the assembler couldn't execute a new assembler after assembling the current message (when it detected there is more data), in the finally block it would "continue" only if the socket was still open. The test case closes the socket after sending 4 messages so when this condition occurred, the assembler failed to continue and data was left in the buffer. Remove the `isOpen()` check in the finally block and always continue if there's not another assembler running and there's data available. INT-3433 More Polishing We can still get starvation if the selector is in a long wait (in select()) when a read is delayed. Whenever a read is delayed, wake the selector so its next select will use the readDelay timeout. INT-3433 Reference Docs Also remove Thread.yield(). Revert redundant boolean return from `TcpNioConnection#checkForAssembler()`
This commit is contained in:
committed by
Artem Bilan
parent
69e20fc7db
commit
3c063a265b
@@ -73,7 +73,6 @@ import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.integration.support.converter.MapMessageConverter;
|
||||
import org.springframework.integration.test.util.SocketUtils;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
import org.springframework.integration.util.CallerBlocksPolicy;
|
||||
import org.springframework.integration.util.CompositeExecutor;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.support.ErrorMessage;
|
||||
@@ -85,6 +84,7 @@ import org.springframework.util.ReflectionUtils.FieldFilter;
|
||||
|
||||
/**
|
||||
* @author Gary Russell
|
||||
* @author John Anderson
|
||||
* @since 2.0
|
||||
*
|
||||
*/
|
||||
@@ -608,7 +608,7 @@ public class TcpNioConnectionTests {
|
||||
|
||||
@Test
|
||||
public void testAllMessagesDelivered() throws Exception {
|
||||
final int numberOfSockets = 25;
|
||||
final int numberOfSockets = 100;
|
||||
final int port = SocketUtils.findAvailableServerSocket();
|
||||
TcpNioServerConnectionFactory factory = new TcpNioServerConnectionFactory(port);
|
||||
factory.setApplicationEventPublisher(mock(ApplicationEventPublisher.class));
|
||||
@@ -616,7 +616,7 @@ public class TcpNioConnectionTests {
|
||||
CompositeExecutor compositeExec = compositeExecutor();
|
||||
|
||||
factory.setTaskExecutor(compositeExec);
|
||||
final CountDownLatch latch = new CountDownLatch(numberOfSockets);
|
||||
final CountDownLatch latch = new CountDownLatch(numberOfSockets * 4);
|
||||
factory.registerListener(new TcpListener() {
|
||||
|
||||
@Override
|
||||
@@ -629,7 +629,7 @@ public class TcpNioConnectionTests {
|
||||
|
||||
});
|
||||
factory.start();
|
||||
|
||||
|
||||
Socket[] sockets = new Socket[numberOfSockets];
|
||||
for (int i = 0; i < numberOfSockets; i++) {
|
||||
Socket socket = null;
|
||||
@@ -651,11 +651,28 @@ public class TcpNioConnectionTests {
|
||||
}
|
||||
Thread.sleep(100);
|
||||
for (int i = 0; i < numberOfSockets; i++) {
|
||||
sockets[i].getOutputStream().write(("...foo2\r\n").getBytes());
|
||||
sockets[i].getOutputStream().write(("...foo2\r\nbar1 and...").getBytes());
|
||||
sockets[i].getOutputStream().flush();
|
||||
}
|
||||
for (int i = 0; i < numberOfSockets; i++) {
|
||||
sockets[i].getOutputStream().write(("...bar2\r\n").getBytes());
|
||||
sockets[i].getOutputStream().flush();
|
||||
}
|
||||
for (int i = 0; i < numberOfSockets; i++) {
|
||||
sockets[i].getOutputStream().write("foo3 and...".getBytes());
|
||||
sockets[i].getOutputStream().flush();
|
||||
}
|
||||
Thread.sleep(100);
|
||||
for (int i = 0; i < numberOfSockets; i++) {
|
||||
sockets[i].getOutputStream().write(("...foo4\r\nbar3 and...").getBytes());
|
||||
sockets[i].getOutputStream().flush();
|
||||
}
|
||||
for (int i = 0; i < numberOfSockets; i++) {
|
||||
sockets[i].getOutputStream().write(("...bar4\r\n").getBytes());
|
||||
sockets[i].close();
|
||||
}
|
||||
|
||||
assertTrue(latch.await(10, TimeUnit.SECONDS));
|
||||
|
||||
assertTrue("latch is still " + latch.getCount(), latch.await(60, TimeUnit.SECONDS));
|
||||
|
||||
factory.stop();
|
||||
}
|
||||
@@ -666,7 +683,7 @@ public class TcpNioConnectionTests {
|
||||
ioExec.setMaxPoolSize(4);
|
||||
ioExec.setQueueCapacity(0);
|
||||
ioExec.setThreadNamePrefix("io-");
|
||||
ioExec.setRejectedExecutionHandler(new CallerBlocksPolicy(5000));
|
||||
ioExec.setRejectedExecutionHandler(new AbortPolicy());
|
||||
ioExec.initialize();
|
||||
ThreadPoolTaskExecutor assemblerExec = new ThreadPoolTaskExecutor();
|
||||
assemblerExec.setCorePoolSize(2);
|
||||
|
||||
Reference in New Issue
Block a user