未验证 提交 5d6720a7 编写于 作者: V Vlad Ilyushchenko 提交者: GitHub

chore(http): refactored http tests to improve stability (#1008)

上级 1aefed87
...@@ -63,6 +63,7 @@ public class HttpConnectionContext implements IOContext, Locality, Mutable, Retr ...@@ -63,6 +63,7 @@ public class HttpConnectionContext implements IOContext, Locality, Mutable, Retr
private int nCompletedRequests; private int nCompletedRequests;
private long totalBytesSent; private long totalBytesSent;
private int receivedBytes; private int receivedBytes;
private final Runnable onPeerDisconnect;
public HttpConnectionContext(HttpContextConfiguration configuration) { public HttpConnectionContext(HttpContextConfiguration configuration) {
this.nf = configuration.getNetworkFacade(); this.nf = configuration.getNetworkFacade();
...@@ -78,6 +79,7 @@ public class HttpConnectionContext implements IOContext, Locality, Mutable, Retr ...@@ -78,6 +79,7 @@ public class HttpConnectionContext implements IOContext, Locality, Mutable, Retr
this.allowDeflateBeforeSend = configuration.allowDeflateBeforeSend(); this.allowDeflateBeforeSend = configuration.allowDeflateBeforeSend();
cairoSecurityContext = new CairoSecurityContextImpl(!configuration.readOnlySecurityContext()); cairoSecurityContext = new CairoSecurityContextImpl(!configuration.readOnlySecurityContext());
this.serverKeepAlive = configuration.getServerKeepAlive(); this.serverKeepAlive = configuration.getServerKeepAlive();
this.onPeerDisconnect = configuration.onPeerDisconnect();
} }
@Override @Override
...@@ -300,7 +302,7 @@ public class HttpConnectionContext implements IOContext, Locality, Mutable, Retr ...@@ -300,7 +302,7 @@ public class HttpConnectionContext implements IOContext, Locality, Mutable, Retr
while (true) { while (true) {
final int n = nf.recv(fd, buf, bufRemaining); final int n = nf.recv(fd, buf, bufRemaining);
if (n < 0) { if (n < 0) {
dispatcher.disconnect(this); handlePeerDisconnect();
break; break;
} }
...@@ -442,7 +444,7 @@ public class HttpConnectionContext implements IOContext, Locality, Mutable, Retr ...@@ -442,7 +444,7 @@ public class HttpConnectionContext implements IOContext, Locality, Mutable, Retr
pendingRetry = true; pendingRetry = true;
return false; return false;
} catch (PeerDisconnectedException ignore) { } catch (PeerDisconnectedException ignore) {
dispatcher.disconnect(this); handlePeerDisconnect();
} catch (PeerIsSlowToReadException e2) { } catch (PeerIsSlowToReadException e2) {
LOG.info().$("peer is slow on running the rerun [fd=").$(fd).$(", thread=") LOG.info().$("peer is slow on running the rerun [fd=").$(fd).$(", thread=")
.$(Thread.currentThread().getId()).$(']').$(); .$(Thread.currentThread().getId()).$(']').$();
...@@ -478,7 +480,7 @@ public class HttpConnectionContext implements IOContext, Locality, Mutable, Retr ...@@ -478,7 +480,7 @@ public class HttpConnectionContext implements IOContext, Locality, Mutable, Retr
LOG.debug().$("peer is slow reader").$(); LOG.debug().$("peer is slow reader").$();
dispatcher.registerChannel(this, IOOperation.WRITE); dispatcher.registerChannel(this, IOOperation.WRITE);
} catch (PeerDisconnectedException ignore) { } catch (PeerDisconnectedException ignore) {
dispatcher.disconnect(this); handlePeerDisconnect();
} catch (ServerDisconnectException ignore) { } catch (ServerDisconnectException ignore) {
LOG.info().$("kicked out [fd=").$(fd).$(']').$(); LOG.info().$("kicked out [fd=").$(fd).$(']').$();
dispatcher.disconnect(this); dispatcher.disconnect(this);
...@@ -524,7 +526,7 @@ public class HttpConnectionContext implements IOContext, Locality, Mutable, Retr ...@@ -524,7 +526,7 @@ public class HttpConnectionContext implements IOContext, Locality, Mutable, Retr
.$(", errno=").$(nf.errno()) .$(", errno=").$(nf.errno())
.$(']').$(); .$(']').$();
// peer disconnect // peer disconnect
dispatcher.disconnect(this); handlePeerDisconnect();
return false; return false;
} }
...@@ -571,7 +573,7 @@ public class HttpConnectionContext implements IOContext, Locality, Mutable, Retr ...@@ -571,7 +573,7 @@ public class HttpConnectionContext implements IOContext, Locality, Mutable, Retr
if (read != 0) { if (read != 0) {
dumpBuffer(recvBuffer, read); dumpBuffer(recvBuffer, read);
LOG.info().$("disconnect after request [fd=").$(fd).$(']').$(); LOG.info().$("disconnect after request [fd=").$(fd).$(']').$();
dispatcher.disconnect(this); handlePeerDisconnect();
busyRecv = false; busyRecv = false;
} else { } else {
processor.onHeadersReady(this); processor.onHeadersReady(this);
...@@ -586,7 +588,7 @@ public class HttpConnectionContext implements IOContext, Locality, Mutable, Retr ...@@ -586,7 +588,7 @@ public class HttpConnectionContext implements IOContext, Locality, Mutable, Retr
scheduleRetry(processor, rescheduleContext); scheduleRetry(processor, rescheduleContext);
busyRecv = false; busyRecv = false;
} catch (PeerDisconnectedException e) { } catch (PeerDisconnectedException e) {
dispatcher.disconnect(this); handlePeerDisconnect();
busyRecv = false; busyRecv = false;
} catch (ServerDisconnectException e) { } catch (ServerDisconnectException e) {
LOG.info().$("kicked out [fd=").$(fd).$(']').$(); LOG.info().$("kicked out [fd=").$(fd).$(']').$();
...@@ -626,7 +628,7 @@ public class HttpConnectionContext implements IOContext, Locality, Mutable, Retr ...@@ -626,7 +628,7 @@ public class HttpConnectionContext implements IOContext, Locality, Mutable, Retr
try { try {
doFail(e, processor); doFail(e, processor);
} catch (PeerDisconnectedException peerDisconnectedException) { } catch (PeerDisconnectedException peerDisconnectedException) {
dispatcher.disconnect(this); handlePeerDisconnect();
} catch (PeerIsSlowToReadException peerIsSlowToReadException) { } catch (PeerIsSlowToReadException peerIsSlowToReadException) {
LOG.info().$("peer is slow to receive failed to retry response [fd=").$(fd).$(']').$(); LOG.info().$("peer is slow to receive failed to retry response [fd=").$(fd).$(']').$();
processor.parkRequest(this); processor.parkRequest(this);
...@@ -638,6 +640,11 @@ public class HttpConnectionContext implements IOContext, Locality, Mutable, Retr ...@@ -638,6 +640,11 @@ public class HttpConnectionContext implements IOContext, Locality, Mutable, Retr
} }
} }
private void handlePeerDisconnect() {
dispatcher.disconnect(this);
onPeerDisconnect.run();
}
private void doFail(HttpException e, HttpRequestProcessor processor) throws private void doFail(HttpException e, HttpRequestProcessor processor) throws
PeerIsSlowToReadException, PeerDisconnectedException, ServerDisconnectException { PeerIsSlowToReadException, PeerDisconnectedException, ServerDisconnectException {
LOG.info().$("failing client query with: ").$(e.getMessage()).$(); LOG.info().$("failing client query with: ").$(e.getMessage()).$();
......
...@@ -29,6 +29,9 @@ import io.questdb.std.datetime.millitime.MillisecondClock; ...@@ -29,6 +29,9 @@ import io.questdb.std.datetime.millitime.MillisecondClock;
public interface HttpContextConfiguration { public interface HttpContextConfiguration {
Runnable NONE= () -> {
};
boolean allowDeflateBeforeSend(); boolean allowDeflateBeforeSend();
MillisecondClock getClock(); MillisecondClock getClock();
...@@ -56,4 +59,8 @@ public interface HttpContextConfiguration { ...@@ -56,4 +59,8 @@ public interface HttpContextConfiguration {
boolean getServerKeepAlive(); boolean getServerKeepAlive();
boolean readOnlySecurityContext(); boolean readOnlySecurityContext();
default Runnable onPeerDisconnect(){
return NONE;
}
} }
...@@ -50,6 +50,7 @@ public class HttpServerConfigurationBuilder { ...@@ -50,6 +50,7 @@ public class HttpServerConfigurationBuilder {
private int rerunProcessingQueueSize = 4096; private int rerunProcessingQueueSize = 4096;
private int receiveBufferSize = 1024 * 1024; private int receiveBufferSize = 1024 * 1024;
private long multipartIdleSpinCount = -1; private long multipartIdleSpinCount = -1;
private Runnable onPeerDisconnect = HttpContextConfiguration.NONE;
public HttpServerConfigurationBuilder withNetwork(NetworkFacade nf) { public HttpServerConfigurationBuilder withNetwork(NetworkFacade nf) {
this.nf = nf; this.nf = nf;
...@@ -96,6 +97,11 @@ public class HttpServerConfigurationBuilder { ...@@ -96,6 +97,11 @@ public class HttpServerConfigurationBuilder {
return this; return this;
} }
public HttpServerConfigurationBuilder withOnPeerDisconnect(Runnable runnable) {
this.onPeerDisconnect = runnable;
return this;
}
public HttpServerConfigurationBuilder withReceiveBufferSize(int receiveBufferSize) { public HttpServerConfigurationBuilder withReceiveBufferSize(int receiveBufferSize) {
this.receiveBufferSize = receiveBufferSize; this.receiveBufferSize = receiveBufferSize;
return this; return this;
...@@ -258,6 +264,11 @@ public class HttpServerConfigurationBuilder { ...@@ -258,6 +264,11 @@ public class HttpServerConfigurationBuilder {
public String getHttpVersion() { public String getHttpVersion() {
return httpProtocolVersion; return httpProtocolVersion;
} }
@Override
public Runnable onPeerDisconnect() {
return onPeerDisconnect;
}
}; };
} }
......
...@@ -26,7 +26,6 @@ package io.questdb.cutlass.http; ...@@ -26,7 +26,6 @@ package io.questdb.cutlass.http;
import io.questdb.cairo.*; import io.questdb.cairo.*;
import io.questdb.cairo.security.AllowAllCairoSecurityContext; import io.questdb.cairo.security.AllowAllCairoSecurityContext;
import io.questdb.cairo.sql.Record;
import io.questdb.cutlass.NetUtils; import io.questdb.cutlass.NetUtils;
import io.questdb.cutlass.http.processors.JsonQueryProcessor; import io.questdb.cutlass.http.processors.JsonQueryProcessor;
import io.questdb.cutlass.http.processors.QueryCache; import io.questdb.cutlass.http.processors.QueryCache;
...@@ -57,7 +56,6 @@ import org.junit.Rule; ...@@ -57,7 +56,6 @@ import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.TemporaryFolder; import org.junit.rules.TemporaryFolder;
import java.io.BufferedInputStream;
import java.io.InputStream; import java.io.InputStream;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier; import java.util.concurrent.CyclicBarrier;
...@@ -1269,7 +1267,7 @@ public class IODispatcherTest { ...@@ -1269,7 +1267,7 @@ public class IODispatcherTest {
public void testImportMultipleOnSameConnectionSlow() throws Exception { public void testImportMultipleOnSameConnectionSlow() throws Exception {
assertMemoryLeak(() -> { assertMemoryLeak(() -> {
final String baseDir = temp.getRoot().getAbsolutePath(); final String baseDir = temp.getRoot().getAbsolutePath();
final DefaultHttpServerConfiguration httpConfiguration = createHttpServerConfiguration(baseDir, false, false); final DefaultHttpServerConfiguration httpConfiguration = createHttpServerConfiguration(baseDir, false);
final WorkerPool workerPool = new WorkerPool(new WorkerPoolConfiguration() { final WorkerPool workerPool = new WorkerPool(new WorkerPoolConfiguration() {
@Override @Override
public int[] getWorkerAffinity() { public int[] getWorkerAffinity() {
...@@ -2108,7 +2106,7 @@ public class IODispatcherTest { ...@@ -2108,7 +2106,7 @@ public class IODispatcherTest {
public void testJsonQueryDataError() throws Exception { public void testJsonQueryDataError() throws Exception {
assertMemoryLeak(() -> { assertMemoryLeak(() -> {
final String baseDir = temp.getRoot().getAbsolutePath(); final String baseDir = temp.getRoot().getAbsolutePath();
final DefaultHttpServerConfiguration httpConfiguration = createHttpServerConfiguration(baseDir, false, false); final DefaultHttpServerConfiguration httpConfiguration = createHttpServerConfiguration(baseDir, false);
final WorkerPool workerPool = new WorkerPool(new WorkerPoolConfiguration() { final WorkerPool workerPool = new WorkerPool(new WorkerPoolConfiguration() {
@Override @Override
public int[] getWorkerAffinity() { public int[] getWorkerAffinity() {
...@@ -3243,7 +3241,7 @@ public class IODispatcherTest { ...@@ -3243,7 +3241,7 @@ public class IODispatcherTest {
public void testJsonQuerySyntaxError() throws Exception { public void testJsonQuerySyntaxError() throws Exception {
assertMemoryLeak(() -> { assertMemoryLeak(() -> {
final String baseDir = temp.getRoot().getAbsolutePath(); final String baseDir = temp.getRoot().getAbsolutePath();
final DefaultHttpServerConfiguration httpConfiguration = createHttpServerConfiguration(baseDir, false, false); final DefaultHttpServerConfiguration httpConfiguration = createHttpServerConfiguration(baseDir, false);
final WorkerPool workerPool = new WorkerPool(new WorkerPoolConfiguration() { final WorkerPool workerPool = new WorkerPool(new WorkerPoolConfiguration() {
@Override @Override
public int[] getWorkerAffinity() { public int[] getWorkerAffinity() {
...@@ -3630,8 +3628,23 @@ public class IODispatcherTest { ...@@ -3630,8 +3628,23 @@ public class IODispatcherTest {
assertMemoryLeak(() -> { assertMemoryLeak(() -> {
final NetworkFacade nf = NetworkFacadeImpl.INSTANCE; final NetworkFacade nf = NetworkFacadeImpl.INSTANCE;
final String baseDir = temp.getRoot().getAbsolutePath(); final String baseDir = temp.getRoot().getAbsolutePath();
final DefaultHttpServerConfiguration httpConfiguration = createHttpServerConfiguration(nf, baseDir, 256, final int tableRowCount = 300_000;
false, false);
SOCountDownLatch peerDisconnectLatch = new SOCountDownLatch(1);
DefaultHttpServerConfiguration httpConfiguration = new HttpServerConfigurationBuilder()
.withNetwork(nf)
.withBaseDir(baseDir)
.withSendBufferSize(256)
.withDumpingTraffic(false)
.withAllowDeflateBeforeSend(false)
.withServerKeepAlive(true)
.withHttpProtocolVersion("HTTP/1.1 ")
.withOnPeerDisconnect(peerDisconnectLatch::countDown)
.build();
QueryCache.configure(httpConfiguration);
final WorkerPool workerPool = new WorkerPool(new WorkerPoolConfiguration() { final WorkerPool workerPool = new WorkerPool(new WorkerPoolConfiguration() {
@Override @Override
public int[] getWorkerAffinity() { public int[] getWorkerAffinity() {
...@@ -3648,8 +3661,11 @@ public class IODispatcherTest { ...@@ -3648,8 +3661,11 @@ public class IODispatcherTest {
return false; return false;
} }
}); });
try (CairoEngine engine = new CairoEngine(new DefaultCairoConfiguration(baseDir));
HttpServer httpServer = new HttpServer(httpConfiguration, workerPool, false)) { try (
CairoEngine engine = new CairoEngine(new DefaultCairoConfiguration(baseDir));
HttpServer httpServer = new HttpServer(httpConfiguration, workerPool, false)
) {
httpServer.bind(new HttpRequestProcessorFactory() { httpServer.bind(new HttpRequestProcessorFactory() {
@Override @Override
public HttpRequestProcessor newInstance() { public HttpRequestProcessor newInstance() {
...@@ -3676,7 +3692,6 @@ public class IODispatcherTest { ...@@ -3676,7 +3692,6 @@ public class IODispatcherTest {
}); });
final AtomicBoolean clientClosed = new AtomicBoolean(false); final AtomicBoolean clientClosed = new AtomicBoolean(false);
final AtomicBoolean serverClosed = new AtomicBoolean(false);
final int minClientReceivedBytesBeforeDisconnect = 180; final int minClientReceivedBytesBeforeDisconnect = 180;
final AtomicLong refClientFd = new AtomicLong(-1); final AtomicLong refClientFd = new AtomicLong(-1);
HttpClientStateListener clientStateListener = new HttpClientStateListener() { HttpClientStateListener clientStateListener = new HttpClientStateListener() {
...@@ -3684,7 +3699,6 @@ public class IODispatcherTest { ...@@ -3684,7 +3699,6 @@ public class IODispatcherTest {
@Override @Override
public void onClosed() { public void onClosed() {
clientClosed.set(true);
} }
@Override @Override
...@@ -3696,6 +3710,7 @@ public class IODispatcherTest { ...@@ -3696,6 +3710,7 @@ public class IODispatcherTest {
if (fd != -1) { if (fd != -1) {
refClientFd.set(-1); refClientFd.set(-1);
nf.close(fd); nf.close(fd);
clientClosed.set(true);
} }
} }
} }
...@@ -3704,11 +3719,14 @@ public class IODispatcherTest { ...@@ -3704,11 +3719,14 @@ public class IODispatcherTest {
try { try {
// create table with all column types // create table with all column types
CairoTestUtils.createTestTable(engine.getConfiguration(), 10000, new Rnd(), CairoTestUtils.createTestTable(
new TestRecord.ArrayBinarySequence()); engine.getConfiguration(),
tableRowCount,
new Rnd(),
new TestRecord.ArrayBinarySequence()
);
// send multipart request to server // send multipart request to server
final String request = "GET /query?query=select+distinct+a+from+x+where+test_latched_counter() HTTP/1.1\r\n" final String request = "GET /query?query=select+distinct+a+from+x+where+test_latched_counter() HTTP/1.1\r\n"
+ "Host: localhost:9001\r\n" + "Connection: keep-alive\r\n" + "Cache-Control: max-age=0\r\n" + "Host: localhost:9001\r\n" + "Connection: keep-alive\r\n" + "Cache-Control: max-age=0\r\n"
+ "Upgrade-Insecure-Requests: 1\r\n" + "Upgrade-Insecure-Requests: 1\r\n"
...@@ -3716,22 +3734,7 @@ public class IODispatcherTest { ...@@ -3716,22 +3734,7 @@ public class IODispatcherTest {
+ "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3\r\n" + "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3\r\n"
+ "Accept-Encoding: gzip, deflate, br\r\n" + "Accept-Encoding: gzip, deflate, br\r\n"
+ "Accept-Language: en-GB,en-US;q=0.9,en;q=0.8\r\n" + "\r\n"; + "Accept-Language: en-GB,en-US;q=0.9,en;q=0.8\r\n" + "\r\n";
TestLatchedCounterFunctionFactory.reset(new TestLatchedCounterFunctionFactory.Callback() {
@Override
public boolean onGet(Record record, int count) {
if (count == 4) {
while (!clientClosed.get()) {
LockSupport.parkNanos(1);
}
}
return true;
}
@Override
public void onClose() {
serverClosed.set(true);
}
});
long fd = nf.socketTcp(true); long fd = nf.socketTcp(true);
try { try {
long sockAddr = nf.sockaddr("127.0.0.1", 9001); long sockAddr = nf.sockaddr("127.0.0.1", 9001);
...@@ -3760,10 +3763,10 @@ public class IODispatcherTest { ...@@ -3760,10 +3763,10 @@ public class IODispatcherTest {
} finally { } finally {
LOG.info().$("Closing client connection").$(); LOG.info().$("Closing client connection").$();
} }
while (!serverClosed.get()) { peerDisconnectLatch.await();
LockSupport.parkNanos(1); // depending on how quick the CI hardware is we may end up processing different
} // number of rows before query is interrupted
Assert.assertEquals(6, TestLatchedCounterFunctionFactory.getCount()); Assert.assertTrue(tableRowCount > TestLatchedCounterFunctionFactory.getCount());
} finally { } finally {
workerPool.halt(); workerPool.halt();
} }
...@@ -4177,7 +4180,7 @@ public class IODispatcherTest { ...@@ -4177,7 +4180,7 @@ public class IODispatcherTest {
public void testSCPConnectDownloadDisconnect() throws Exception { public void testSCPConnectDownloadDisconnect() throws Exception {
assertMemoryLeak(() -> { assertMemoryLeak(() -> {
final String baseDir = temp.getRoot().getAbsolutePath(); final String baseDir = temp.getRoot().getAbsolutePath();
final DefaultHttpServerConfiguration httpConfiguration = createHttpServerConfiguration(baseDir, false, false); final DefaultHttpServerConfiguration httpConfiguration = createHttpServerConfiguration(baseDir, false);
final WorkerPool workerPool = new WorkerPool(new WorkerPoolConfiguration() { final WorkerPool workerPool = new WorkerPool(new WorkerPoolConfiguration() {
@Override @Override
public int[] getWorkerAffinity() { public int[] getWorkerAffinity() {
...@@ -4215,7 +4218,7 @@ public class IODispatcherTest { ...@@ -4215,7 +4218,7 @@ public class IODispatcherTest {
Rnd rnd = new Rnd(); Rnd rnd = new Rnd();
final int diskBufferLen = 1024 * 1024; final int diskBufferLen = 1024 * 1024;
writeRandomFile(path, rnd, 122222212222L, diskBufferLen); writeRandomFile(path, rnd, 122222212222L);
// httpServer.getStartedLatch().await(); // httpServer.getStartedLatch().await();
...@@ -4348,7 +4351,7 @@ public class IODispatcherTest { ...@@ -4348,7 +4351,7 @@ public class IODispatcherTest {
public void testSCPFullDownload() throws Exception { public void testSCPFullDownload() throws Exception {
assertMemoryLeak(() -> { assertMemoryLeak(() -> {
final String baseDir = temp.getRoot().getAbsolutePath(); final String baseDir = temp.getRoot().getAbsolutePath();
final DefaultHttpServerConfiguration httpConfiguration = createHttpServerConfiguration(baseDir, false, false); final DefaultHttpServerConfiguration httpConfiguration = createHttpServerConfiguration(baseDir, false);
final WorkerPool workerPool = new WorkerPool(new WorkerPoolConfiguration() { final WorkerPool workerPool = new WorkerPool(new WorkerPoolConfiguration() {
@Override @Override
public int[] getWorkerAffinity() { public int[] getWorkerAffinity() {
...@@ -4386,7 +4389,7 @@ public class IODispatcherTest { ...@@ -4386,7 +4389,7 @@ public class IODispatcherTest {
Rnd rnd = new Rnd(); Rnd rnd = new Rnd();
final int diskBufferLen = 1024 * 1024; final int diskBufferLen = 1024 * 1024;
writeRandomFile(path, rnd, 122299092L, diskBufferLen); writeRandomFile(path, rnd, 122299092L);
long fd = Net.socketTcp(true); long fd = Net.socketTcp(true);
try { try {
...@@ -4543,7 +4546,7 @@ public class IODispatcherTest { ...@@ -4543,7 +4546,7 @@ public class IODispatcherTest {
Rnd rnd = new Rnd(); Rnd rnd = new Rnd();
final int diskBufferLen = 1024 * 1024; final int diskBufferLen = 1024 * 1024;
writeRandomFile(path, rnd, 122222212222L, diskBufferLen); writeRandomFile(path, rnd, 122222212222L);
// httpServer.getStartedLatch().await(); // httpServer.getStartedLatch().await();
...@@ -5297,6 +5300,7 @@ public class IODispatcherTest { ...@@ -5297,6 +5300,7 @@ public class IODispatcherTest {
final NetworkFacade nf = NetworkFacadeImpl.INSTANCE; final NetworkFacade nf = NetworkFacadeImpl.INSTANCE;
final AtomicInteger requestsReceived = new AtomicInteger(); final AtomicInteger requestsReceived = new AtomicInteger();
final AtomicBoolean finished = new AtomicBoolean(false); final AtomicBoolean finished = new AtomicBoolean(false);
final SOCountDownLatch senderHalt = new SOCountDownLatch(senderCount);
try (IODispatcher<HttpConnectionContext> dispatcher = IODispatchers.create( try (IODispatcher<HttpConnectionContext> dispatcher = IODispatchers.create(
new DefaultIODispatcherConfiguration(), new DefaultIODispatcherConfiguration(),
(fd, dispatcher1) -> new HttpConnectionContext(httpServerConfiguration.getHttpContextConfiguration()).of(fd, dispatcher1) (fd, dispatcher1) -> new HttpConnectionContext(httpServerConfiguration.getHttpContextConfiguration()).of(fd, dispatcher1)
...@@ -5310,7 +5314,7 @@ public class IODispatcherTest { ...@@ -5310,7 +5314,7 @@ public class IODispatcherTest {
AtomicBoolean serverRunning = new AtomicBoolean(true); AtomicBoolean serverRunning = new AtomicBoolean(true);
CountDownLatch serverHaltLatch = new CountDownLatch(serverThreadCount); SOCountDownLatch serverHaltLatch = new SOCountDownLatch(serverThreadCount);
for (int j = 0; j < serverThreadCount; j++) { for (int j = 0; j < serverThreadCount; j++) {
new Thread(() -> { new Thread(() -> {
final StringSink sink = new StringSink(); final StringSink sink = new StringSink();
...@@ -5414,6 +5418,7 @@ public class IODispatcherTest { ...@@ -5414,6 +5418,7 @@ public class IODispatcherTest {
} finally { } finally {
completedCount.incrementAndGet(); completedCount.incrementAndGet();
Net.freeSockAddr(sockAddr); Net.freeSockAddr(sockAddr);
senderHalt.countDown();
} }
}).start(); }).start();
} }
...@@ -5439,6 +5444,7 @@ public class IODispatcherTest { ...@@ -5439,6 +5444,7 @@ public class IODispatcherTest {
serverHaltLatch.await(); serverHaltLatch.await();
} finally { } finally {
finished.set(true); finished.set(true);
senderHalt.await();
} }
Assert.assertEquals(N * senderCount, requestsReceived.get()); Assert.assertEquals(N * senderCount, requestsReceived.get());
}); });
...@@ -5542,15 +5548,14 @@ public class IODispatcherTest { ...@@ -5542,15 +5548,14 @@ public class IODispatcherTest {
@NotNull @NotNull
private DefaultHttpServerConfiguration createHttpServerConfiguration( private DefaultHttpServerConfiguration createHttpServerConfiguration(
String baseDir, String baseDir,
boolean dumpTraffic, boolean dumpTraffic
boolean allowDeflateBeforeSend
) { ) {
return createHttpServerConfiguration( return createHttpServerConfiguration(
NetworkFacadeImpl.INSTANCE, NetworkFacadeImpl.INSTANCE,
baseDir, baseDir,
1024 * 1024, 1024 * 1024,
dumpTraffic, dumpTraffic,
allowDeflateBeforeSend false
); );
} }
...@@ -5562,7 +5567,15 @@ public class IODispatcherTest { ...@@ -5562,7 +5567,15 @@ public class IODispatcherTest {
boolean dumpTraffic, boolean dumpTraffic,
boolean allowDeflateBeforeSend boolean allowDeflateBeforeSend
) { ) {
return createHttpServerConfiguration(nf, baseDir, sendBufferSize, dumpTraffic, allowDeflateBeforeSend, true, "HTTP/1.1 "); return createHttpServerConfiguration(
nf,
baseDir,
sendBufferSize,
dumpTraffic,
allowDeflateBeforeSend,
true,
"HTTP/1.1 "
);
} }
@NotNull @NotNull
...@@ -5633,24 +5646,24 @@ public class IODispatcherTest { ...@@ -5633,24 +5646,24 @@ public class IODispatcherTest {
.run(code); .run(code);
} }
private void writeRandomFile(Path path, Rnd rnd, long lastModified, int bufLen) { private void writeRandomFile(Path path, Rnd rnd, long lastModified) {
if (Files.exists(path)) { if (Files.exists(path)) {
Assert.assertTrue(Files.remove(path)); Assert.assertTrue(Files.remove(path));
} }
long fd = Files.openAppend(path); long fd = Files.openAppend(path);
long buf = Unsafe.malloc(bufLen); // 1Mb buffer long buf = Unsafe.malloc(1048576); // 1Mb buffer
for (int i = 0; i < bufLen; i++) { for (int i = 0; i < 1048576; i++) {
Unsafe.getUnsafe().putByte(buf + i, rnd.nextByte()); Unsafe.getUnsafe().putByte(buf + i, rnd.nextByte());
} }
for (int i = 0; i < 20; i++) { for (int i = 0; i < 20; i++) {
Assert.assertEquals(bufLen, Files.append(fd, buf, bufLen)); Assert.assertEquals(1048576, Files.append(fd, buf, 1048576));
} }
Files.close(fd); Files.close(fd);
Files.setLastModified(path, lastModified); Files.setLastModified(path, lastModified);
Unsafe.free(buf, bufLen); Unsafe.free(buf, 1048576);
} }
private static class QueryThread extends Thread { private static class QueryThread extends Thread {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册