use of java.util.concurrent.Exchanger in project jetty.project by eclipse.
the class ConnectorTimeoutTest method testMaxIdleWithRequest10ClientIgnoresClose.
@Test(timeout = 60000)
public void testMaxIdleWithRequest10ClientIgnoresClose() throws Exception {
final Exchanger<EndPoint> exchanger = new Exchanger<>();
configureServer(new HelloWorldHandler() {
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
try {
exchanger.exchange(baseRequest.getHttpChannel().getEndPoint());
} catch (Exception e) {
e.printStackTrace();
}
super.handle(target, baseRequest, request, response);
}
});
Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort());
client.setSoTimeout(10000);
Assert.assertFalse(client.isClosed());
OutputStream os = client.getOutputStream();
InputStream is = client.getInputStream();
os.write(("GET / HTTP/1.0\r\n" + "host: " + _serverURI.getHost() + ":" + _serverURI.getPort() + "\r\n" + "connection: close\r\n" + "\r\n").getBytes("utf-8"));
os.flush();
// Get the server side endpoint
EndPoint endPoint = exchanger.exchange(null, 10, TimeUnit.SECONDS);
if (endPoint instanceof SslConnection.DecryptedEndPoint)
endPoint = endPoint.getConnection().getEndPoint();
// read the response
String result = IO.toString(is);
Assert.assertThat("OK", result, Matchers.containsString("200 OK"));
// check client reads EOF
Assert.assertEquals(-1, is.read());
Assert.assertTrue(endPoint.isOutputShutdown());
Thread.sleep(2 * MAX_IDLE_TIME);
// further writes will get broken pipe or similar
try {
long end = System.currentTimeMillis() + MAX_IDLE_TIME + 3000;
while (System.currentTimeMillis() < end) {
os.write("THIS DATA SHOULD NOT BE PARSED!\n\n".getBytes("utf-8"));
os.flush();
Thread.sleep(100);
}
Assert.fail("half close should have timed out");
} catch (SocketException e) {
// expected
// Give the SSL onClose time to act
Thread.sleep(100);
}
// check the server side is closed
Assert.assertFalse(endPoint.isOpen());
}
use of java.util.concurrent.Exchanger in project jetty.project by eclipse.
the class ThreadStarvationTest method testFailureStarvation.
@Test
public void testFailureStarvation() throws Exception {
try (StacklessLogging stackless = new StacklessLogging(HttpChannel.class)) {
int acceptors = 0;
int selectors = 1;
int maxThreads = 10;
final int barried = maxThreads - acceptors - selectors * 2;
final CyclicBarrier barrier = new CyclicBarrier(barried);
QueuedThreadPool threadPool = new QueuedThreadPool(maxThreads, maxThreads);
threadPool.setDetailedDump(true);
_server = new Server(threadPool);
ServerConnector connector = new ServerConnector(_server, acceptors, selectors) {
@Override
protected ChannelEndPoint newEndPoint(SocketChannel channel, ManagedSelector selectSet, SelectionKey key) throws IOException {
return new SocketChannelEndPoint(channel, selectSet, key, getScheduler()) {
@Override
public boolean flush(ByteBuffer... buffers) throws IOException {
super.flush(buffers[0]);
throw new IOException("TEST FAILURE");
}
};
}
};
connector.setIdleTimeout(Long.MAX_VALUE);
_server.addConnector(connector);
final AtomicInteger count = new AtomicInteger(0);
_server.setHandler(new AbstractHandler() {
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
int c = count.getAndIncrement();
try {
if (c < barried) {
barrier.await(10, TimeUnit.SECONDS);
}
} catch (InterruptedException | BrokenBarrierException | TimeoutException e) {
throw new ServletException(e);
}
baseRequest.setHandled(true);
response.setStatus(200);
response.setContentLength(13);
response.getWriter().print("Hello World!\n");
response.getWriter().flush();
}
});
_server.start();
List<Socket> sockets = new ArrayList<>();
for (int i = 0; i < maxThreads * 2; ++i) {
Socket socket = new Socket("localhost", connector.getLocalPort());
sockets.add(socket);
OutputStream output = socket.getOutputStream();
String request = "" + "GET / HTTP/1.1\r\n" + "Host: localhost\r\n" + // "Connection: close\r\n" +
"\r\n";
output.write(request.getBytes(StandardCharsets.UTF_8));
output.flush();
}
byte[] buffer = new byte[48 * 1024];
List<Exchanger<Integer>> totals = new ArrayList<>();
for (Socket socket : sockets) {
final Exchanger<Integer> x = new Exchanger<>();
totals.add(x);
final InputStream input = socket.getInputStream();
new Thread() {
@Override
public void run() {
int read = 0;
try {
// look for CRLFCRLF
StringBuilder header = new StringBuilder();
int state = 0;
while (state < 4 && header.length() < 2048) {
int ch = input.read();
if (ch < 0)
break;
header.append((char) ch);
switch(state) {
case 0:
if (ch == '\r')
state = 1;
break;
case 1:
if (ch == '\n')
state = 2;
else
state = 0;
break;
case 2:
if (ch == '\r')
state = 3;
else
state = 0;
break;
case 3:
if (ch == '\n')
state = 4;
else
state = 0;
break;
}
}
read = input.read(buffer);
} catch (IOException e) {
// e.printStackTrace();
} finally {
try {
x.exchange(read);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
for (Exchanger<Integer> x : totals) {
Integer read = x.exchange(-1, 10, TimeUnit.SECONDS);
Assert.assertEquals(-1, read.intValue());
}
// We could read everything, good.
for (Socket socket : sockets) socket.close();
_server.stop();
}
}
use of java.util.concurrent.Exchanger in project jetty.project by eclipse.
the class HttpClientTest method setOnCompleteCallbackWithBlockingSend.
@Test
public void setOnCompleteCallbackWithBlockingSend() throws Exception {
final byte[] content = new byte[512];
new Random().nextBytes(content);
start(new AbstractHandler() {
@Override
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
baseRequest.setHandled(true);
response.getOutputStream().write(content);
}
});
final Exchanger<Response> ex = new Exchanger<>();
BufferingResponseListener listener = new BufferingResponseListener() {
@Override
public void onComplete(Result result) {
try {
ex.exchange(result.getResponse());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
client.newRequest("localhost", connector.getLocalPort()).scheme(scheme).send(listener);
Response response = ex.exchange(null);
Assert.assertEquals(200, response.getStatus());
Assert.assertArrayEquals(content, listener.getContent());
}
use of java.util.concurrent.Exchanger in project hbase by apache.
the class TestReadOnlyZKClient method testNotCloseZkWhenPending.
@Test
public void testNotCloseZkWhenPending() throws Exception {
ZooKeeper mockedZK = mock(ZooKeeper.class);
Exchanger<AsyncCallback.DataCallback> exchanger = new Exchanger<>();
doAnswer(i -> {
exchanger.exchange(i.getArgument(2));
return null;
}).when(mockedZK).getData(anyString(), anyBoolean(), any(AsyncCallback.DataCallback.class), any());
doAnswer(i -> null).when(mockedZK).close();
when(mockedZK.getState()).thenReturn(ZooKeeper.States.CONNECTED);
RO_ZK.zookeeper = mockedZK;
CompletableFuture<byte[]> future = RO_ZK.get(PATH);
AsyncCallback.DataCallback callback = exchanger.exchange(null);
// 2 * keep alive time to ensure that we will not close the zk when there are pending requests
Thread.sleep(6000);
assertNotNull(RO_ZK.zookeeper);
verify(mockedZK, never()).close();
callback.processResult(Code.OK.intValue(), PATH, null, DATA, null);
assertArrayEquals(DATA, future.get());
// now we will close the idle connection.
waitForIdleConnectionClosed();
verify(mockedZK, times(1)).close();
}
use of java.util.concurrent.Exchanger in project netty by netty.
the class FlowControlHandlerTest method testFlowToggleAutoRead.
/**
* The {@link FlowControlHandler} will pass down messages one by one
* if {@link ChannelConfig#setAutoRead(boolean)} is being toggled.
*/
@Test
public void testFlowToggleAutoRead() throws Exception {
final Exchanger<Channel> peerRef = new Exchanger<Channel>();
final CountDownLatch msgRcvLatch1 = new CountDownLatch(1);
final CountDownLatch msgRcvLatch2 = new CountDownLatch(1);
final CountDownLatch msgRcvLatch3 = new CountDownLatch(1);
final CountDownLatch setAutoReadLatch1 = new CountDownLatch(1);
final CountDownLatch setAutoReadLatch2 = new CountDownLatch(1);
ChannelInboundHandlerAdapter handler = new ChannelInboundHandlerAdapter() {
private int msgRcvCount;
private int expectedMsgCount;
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
peerRef.exchange(ctx.channel(), 1L, SECONDS);
ctx.fireChannelActive();
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws InterruptedException {
ReferenceCountUtil.release(msg);
// Disable auto reading after each message
ctx.channel().config().setAutoRead(false);
if (msgRcvCount++ != expectedMsgCount) {
return;
}
switch(msgRcvCount) {
case 1:
msgRcvLatch1.countDown();
if (setAutoReadLatch1.await(1L, SECONDS)) {
++expectedMsgCount;
}
break;
case 2:
msgRcvLatch2.countDown();
if (setAutoReadLatch2.await(1L, SECONDS)) {
++expectedMsgCount;
}
break;
default:
msgRcvLatch3.countDown();
break;
}
}
};
FlowControlHandler flow = new FlowControlHandler();
Channel server = newServer(true, flow, handler);
Channel client = newClient(server.localAddress());
try {
// The client connection on the server side
Channel peer = peerRef.exchange(null, 1L, SECONDS);
client.writeAndFlush(newOneMessage()).syncUninterruptibly();
// channelRead(1)
assertTrue(msgRcvLatch1.await(1L, SECONDS));
// channelRead(2)
peer.config().setAutoRead(true);
setAutoReadLatch1.countDown();
assertTrue(msgRcvLatch1.await(1L, SECONDS));
// channelRead(3)
peer.config().setAutoRead(true);
setAutoReadLatch2.countDown();
assertTrue(msgRcvLatch3.await(1L, SECONDS));
assertTrue(flow.isQueueEmpty());
} finally {
client.close();
server.close();
}
}
Aggregations