use of io.questdb.mp.SOCountDownLatch in project questdb by bluestreak01.
the class IODispatcherTest method testSendTimeout.
@Test
public void testSendTimeout() throws Exception {
LOG.info().$("started testSendHttpGet").$();
final String request = "GET /status?x=1&a=%26b&c&d=x HTTP/1.1\r\n" + "Host: localhost:9000\r\n" + "Connection: keep-alive\r\n" + "Cache-Control: max-age=0\r\n" + "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n" + "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.48 Safari/537.36\r\n" + "Accept-Encoding: gzip,deflate,sdch\r\n" + "Accept-Language: en-US,en;q=0.8\r\n" + "Cookie: textwrapon=false; textautoformat=false; wysiwyg=textarea\r\n" + "\r\n";
assertMemoryLeak(() -> {
HttpServerConfiguration httpServerConfiguration = new DefaultHttpServerConfiguration();
SOCountDownLatch connectLatch = new SOCountDownLatch(1);
SOCountDownLatch contextClosedLatch = new SOCountDownLatch(1);
AtomicInteger closeCount = new AtomicInteger(0);
try (IODispatcher<HttpConnectionContext> dispatcher = IODispatchers.create(new DefaultIODispatcherConfiguration() {
@Override
public long getIdleConnectionTimeout() {
// 0.5s idle timeout
return 500;
}
@Override
public boolean getPeerNoLinger() {
return false;
}
}, new IOContextFactory<HttpConnectionContext>() {
@Override
public HttpConnectionContext newInstance(long fd, IODispatcher<HttpConnectionContext> dispatcher1) {
connectLatch.countDown();
return new HttpConnectionContext(httpServerConfiguration.getHttpContextConfiguration()) {
@Override
public void close() {
// context is closed
if (closeCount.incrementAndGet() == 1) {
super.close();
contextClosedLatch.countDown();
}
}
}.of(fd, dispatcher1);
}
})) {
StringSink sink = new StringSink();
HttpRequestProcessorSelector selector = new HttpRequestProcessorSelector() {
@Override
public HttpRequestProcessor select(CharSequence url) {
return null;
}
@Override
public HttpRequestProcessor getDefaultProcessor() {
return new HttpRequestProcessor() {
@Override
public void onHeadersReady(HttpConnectionContext connectionContext) {
HttpRequestHeader headers = connectionContext.getRequestHeader();
sink.put(headers.getMethodLine());
sink.put("\r\n");
ObjList<CharSequence> headerNames = headers.getHeaderNames();
for (int i = 0, n = headerNames.size(); i < n; i++) {
sink.put(headerNames.getQuick(i)).put(':');
sink.put(headers.getHeader(headerNames.getQuick(i)));
sink.put("\r\n");
}
sink.put("\r\n");
}
};
}
@Override
public void close() {
}
};
AtomicBoolean serverRunning = new AtomicBoolean(true);
SOCountDownLatch serverHaltLatch = new SOCountDownLatch(1);
new Thread(() -> {
while (serverRunning.get()) {
dispatcher.run(0);
dispatcher.processIOQueue((operation, context) -> context.handleClientOperation(operation, selector, EmptyRescheduleContext));
}
serverHaltLatch.countDown();
}).start();
long fd = Net.socketTcp(true);
try {
long sockAddr = Net.sockaddr("127.0.0.1", 9001);
try {
TestUtils.assertConnect(fd, sockAddr);
Net.setTcpNoDelay(fd, true);
connectLatch.await();
int len = request.length();
long buffer = TestUtils.toMemory(request);
try {
int part1 = len / 2;
Assert.assertEquals(part1, Net.send(fd, buffer, part1));
Os.sleep(1000);
Assert.assertEquals(len - part1, Net.send(fd, buffer + part1, len - part1));
} finally {
Unsafe.free(buffer, len, MemoryTag.NATIVE_DEFAULT);
}
contextClosedLatch.await();
Assert.assertEquals(0, dispatcher.getConnectionCount());
serverRunning.set(false);
serverHaltLatch.await();
Assert.assertEquals(0, dispatcher.getConnectionCount());
// do not close client side before server does theirs
Assert.assertTrue(Net.isDead(fd));
TestUtils.assertEquals("", sink);
} finally {
Net.freeSockAddr(sockAddr);
}
} finally {
Net.close(fd);
LOG.info().$("closed [fd=").$(fd).$(']').$();
}
Assert.assertEquals(1, closeCount.get());
}
});
}
use of io.questdb.mp.SOCountDownLatch in project questdb by bluestreak01.
the class IODispatcherTest method testSendHttpGet.
@Test
public void testSendHttpGet() throws Exception {
LOG.info().$("started testSendHttpGet").$();
final String request = "GET /status?x=1&a=%26b&c&d=x HTTP/1.1\r\n" + "Host: localhost:9000\r\n" + "Connection: keep-alive\r\n" + "Cache-Control: max-age=0\r\n" + "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n" + "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.48 Safari/537.36\r\n" + "Accept-Encoding: gzip,deflate,sdch\r\n" + "Accept-Language: en-US,en;q=0.8\r\n" + "Cookie: textwrapon=false; textautoformat=false; wysiwyg=textarea\r\n" + "\r\n";
// the difference between request and expected is url encoding (and ':' padding, which can easily be fixed)
final String expected = "GET /status?x=1&a=&b&c&d=x HTTP/1.1\r\n" + "host:localhost:9000\r\n" + "connection:keep-alive\r\n" + "cache-control:max-age=0\r\n" + "accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n" + "user-agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.48 Safari/537.36\r\n" + "accept-encoding:gzip,deflate,sdch\r\n" + "accept-language:en-US,en;q=0.8\r\n" + "cookie:textwrapon=false; textautoformat=false; wysiwyg=textarea\r\n" + "\r\n";
assertMemoryLeak(() -> {
HttpServerConfiguration httpServerConfiguration = new DefaultHttpServerConfiguration();
SOCountDownLatch connectLatch = new SOCountDownLatch(1);
SOCountDownLatch contextClosedLatch = new SOCountDownLatch(1);
SOCountDownLatch requestReceivedLatch = new SOCountDownLatch(1);
AtomicInteger closeCount = new AtomicInteger(0);
try (IODispatcher<HttpConnectionContext> dispatcher = IODispatchers.create(new DefaultIODispatcherConfiguration(), new IOContextFactory<HttpConnectionContext>() {
@Override
public HttpConnectionContext newInstance(long fd, IODispatcher<HttpConnectionContext> dispatcher1) {
connectLatch.countDown();
return new HttpConnectionContext(httpServerConfiguration.getHttpContextConfiguration()) {
@Override
public void close() {
// context is closed
if (closeCount.incrementAndGet() == 1) {
super.close();
contextClosedLatch.countDown();
}
}
}.of(fd, dispatcher1);
}
})) {
StringSink sink = new StringSink();
final HttpRequestProcessorSelector selector = new HttpRequestProcessorSelector() {
@Override
public HttpRequestProcessor select(CharSequence url) {
return new HttpRequestProcessor() {
@Override
public void onHeadersReady(HttpConnectionContext context) {
HttpRequestHeader headers = context.getRequestHeader();
sink.put(headers.getMethodLine());
sink.put("\r\n");
ObjList<CharSequence> headerNames = headers.getHeaderNames();
for (int i = 0, n = headerNames.size(); i < n; i++) {
sink.put(headerNames.getQuick(i)).put(':');
sink.put(headers.getHeader(headerNames.getQuick(i)));
sink.put("\r\n");
}
sink.put("\r\n");
requestReceivedLatch.countDown();
}
};
}
@Override
public HttpRequestProcessor getDefaultProcessor() {
return null;
}
@Override
public void close() {
}
};
AtomicBoolean serverRunning = new AtomicBoolean(true);
SOCountDownLatch serverHaltLatch = new SOCountDownLatch(1);
new Thread(() -> {
while (serverRunning.get()) {
dispatcher.run(0);
dispatcher.processIOQueue((operation, context) -> context.handleClientOperation(operation, selector, EmptyRescheduleContext));
}
serverHaltLatch.countDown();
}).start();
long fd = Net.socketTcp(true);
try {
long sockAddr = Net.sockaddr("127.0.0.1", 9001);
try {
TestUtils.assertConnect(fd, sockAddr);
connectLatch.await();
int len = request.length();
long buffer = TestUtils.toMemory(request);
try {
Assert.assertEquals(len, Net.send(fd, buffer, len));
} finally {
Unsafe.free(buffer, len, MemoryTag.NATIVE_DEFAULT);
}
// do not disconnect right away, wait for server to receive the request
requestReceivedLatch.await();
Assert.assertEquals(0, Net.close(fd));
LOG.info().$("closed [fd=").$(fd).$(']').$();
fd = -1;
contextClosedLatch.await();
serverRunning.set(false);
serverHaltLatch.await();
Assert.assertEquals(0, dispatcher.getConnectionCount());
TestUtils.assertEquals(expected, sink);
} finally {
Net.freeSockAddr(sockAddr);
}
} finally {
if (fd != -1) {
Net.close(fd);
}
}
Assert.assertEquals(1, closeCount.get());
}
});
}
use of io.questdb.mp.SOCountDownLatch in project questdb by bluestreak01.
the class IODispatcherTest method testConnectDisconnect.
@Test
public void testConnectDisconnect() throws Exception {
LOG.info().$("started testConnectDisconnect").$();
assertMemoryLeak(() -> {
HttpServerConfiguration httpServerConfiguration = new DefaultHttpServerConfiguration();
SOCountDownLatch connectLatch = new SOCountDownLatch(1);
SOCountDownLatch contextClosedLatch = new SOCountDownLatch(1);
AtomicInteger closeCount = new AtomicInteger(0);
try (IODispatcher<HttpConnectionContext> dispatcher = IODispatchers.create(new DefaultIODispatcherConfiguration(), new IOContextFactory<HttpConnectionContext>() {
@Override
public HttpConnectionContext newInstance(long fd, IODispatcher<HttpConnectionContext> dispatcher1) {
connectLatch.countDown();
return new HttpConnectionContext(httpServerConfiguration.getHttpContextConfiguration()) {
@Override
public void close() {
// context is closed
if (closeCount.incrementAndGet() == 1) {
super.close();
contextClosedLatch.countDown();
}
}
}.of(fd, dispatcher1);
}
})) {
HttpRequestProcessorSelector selector = new HttpRequestProcessorSelector() {
@Override
public HttpRequestProcessor select(CharSequence url) {
return null;
}
@Override
public HttpRequestProcessor getDefaultProcessor() {
return new HttpRequestProcessor() {
};
}
@Override
public void close() {
}
};
AtomicBoolean serverRunning = new AtomicBoolean(true);
SOCountDownLatch serverHaltLatch = new SOCountDownLatch(1);
new Thread(() -> {
while (serverRunning.get()) {
dispatcher.run(0);
dispatcher.processIOQueue((operation, context) -> context.handleClientOperation(operation, selector, EmptyRescheduleContext));
}
serverHaltLatch.countDown();
}).start();
long fd = Net.socketTcp(true);
try {
long sockAddr = Net.sockaddr("127.0.0.1", 9001);
try {
try {
TestUtils.assertConnect(fd, sockAddr);
connectLatch.await();
Assert.assertEquals(0, Net.close(fd));
LOG.info().$("closed [fd=").$(fd).$(']').$();
fd = -1;
contextClosedLatch.await();
} finally {
serverRunning.set(false);
serverHaltLatch.await();
}
Assert.assertEquals(0, dispatcher.getConnectionCount());
} finally {
Net.freeSockAddr(sockAddr);
}
} finally {
if (fd != -1) {
Net.close(fd);
}
}
Assert.assertEquals(1, closeCount.get());
}
});
}
use of io.questdb.mp.SOCountDownLatch in project questdb by bluestreak01.
the class IODispatcherTest method testBiasWrite.
@Test
public void testBiasWrite() throws Exception {
LOG.info().$("started testBiasWrite").$();
assertMemoryLeak(() -> {
SOCountDownLatch connectLatch = new SOCountDownLatch(1);
SOCountDownLatch contextClosedLatch = new SOCountDownLatch(1);
try (IODispatcher<HelloContext> dispatcher = IODispatchers.create(new DefaultIODispatcherConfiguration() {
@Override
public int getInitialBias() {
return IODispatcherConfiguration.BIAS_WRITE;
}
@Override
public boolean getPeerNoLinger() {
return false;
}
}, (fd, dispatcher1) -> {
connectLatch.countDown();
return new HelloContext(fd, contextClosedLatch, dispatcher1);
})) {
AtomicBoolean serverRunning = new AtomicBoolean(true);
SOCountDownLatch serverHaltLatch = new SOCountDownLatch(1);
new Thread(() -> {
while (serverRunning.get()) {
dispatcher.run(0);
dispatcher.processIOQueue((operation, context) -> {
if (operation == IOOperation.WRITE) {
Assert.assertEquals(1024, Net.send(context.getFd(), context.buffer, 1024));
context.dispatcher.disconnect(context, IODispatcher.DISCONNECT_REASON_TEST);
}
});
}
serverHaltLatch.countDown();
}).start();
long fd = Net.socketTcp(true);
try {
long sockAddr = Net.sockaddr("127.0.0.1", 9001);
try {
try {
TestUtils.assertConnect(fd, sockAddr);
connectLatch.await();
long buffer = Unsafe.malloc(2048, MemoryTag.NATIVE_DEFAULT);
try {
Assert.assertEquals(1024, Net.recv(fd, buffer, 1024));
} finally {
Unsafe.free(buffer, 2048, MemoryTag.NATIVE_DEFAULT);
}
Assert.assertEquals(0, Net.close(fd));
LOG.info().$("closed [fd=").$(fd).$(']').$();
fd = -1;
contextClosedLatch.await();
} finally {
serverRunning.set(false);
serverHaltLatch.await();
}
Assert.assertEquals(0, dispatcher.getConnectionCount());
} finally {
Net.freeSockAddr(sockAddr);
}
} finally {
if (fd != -1) {
Net.close(fd);
}
}
}
});
}
use of io.questdb.mp.SOCountDownLatch in project questdb by bluestreak01.
the class TxnScoreboardTest method testStressOpenParallel.
@Test
public void testStressOpenParallel() throws Exception {
TestUtils.assertMemoryLeak(() -> {
int parallel = 16;
int iterations = (int) 1E3;
SOCountDownLatch latch = new SOCountDownLatch(parallel);
AtomicInteger errors = new AtomicInteger();
for (int i = 0; i < parallel; i++) {
new Thread(() -> {
try (final Path shmPath = new Path()) {
for (int j = 0; j < iterations; j++) {
// noinspection EmptyTryBlock
try (TxnScoreboard ignored = new TxnScoreboard(FilesFacadeImpl.INSTANCE, shmPath.of(root), 1024)) {
// empty body because we need to close this
} catch (Exception ex) {
ex.printStackTrace();
errors.incrementAndGet();
break;
}
}
}
latch.countDown();
}).start();
}
latch.await();
Assert.assertEquals(0, errors.get());
});
}
Aggregations