Skip to content

Commit 3b0e884

Browse files
Improve usage if native ByteBuf
Improve performances by using native ByteBuf instead of using wrapped byte array. Include Benchmark as Integration tests
1 parent 5174335 commit 3b0e884

File tree

9 files changed

+269
-64
lines changed

9 files changed

+269
-64
lines changed

WaarpCommon/src/main/java/org/waarp/common/utility/WaarpNettyUtil.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import io.netty.bootstrap.Bootstrap;
2323
import io.netty.bootstrap.ServerBootstrap;
2424
import io.netty.buffer.ByteBuf;
25+
import io.netty.buffer.ByteBufAllocator;
2526
import io.netty.buffer.PooledByteBufAllocator;
2627
import io.netty.channel.ChannelOption;
2728
import io.netty.channel.EventLoopGroup;
@@ -251,4 +252,23 @@ public static ByteBuf slice(final ByteBuf byteBuf, final int start,
251252
bufSliced.writerIndex(0);
252253
return bufSliced;
253254
}
255+
256+
/**
257+
* Replace the arrays with one Pooled ByteBuf (not wrapped)
258+
*
259+
* @param arrays
260+
*
261+
* @return the ByteBuf from pool
262+
*/
263+
public static ByteBuf wrappedBuffer(byte[]... arrays) {
264+
int size = 0;
265+
for (byte[] array : arrays) {
266+
size += array.length;
267+
}
268+
final ByteBuf finalByteBuf = ByteBufAllocator.DEFAULT.buffer(size);
269+
for (byte[] array : arrays) {
270+
finalByteBuf.writeBytes(array);
271+
}
272+
return finalByteBuf;
273+
}
254274
}

WaarpR66/src/main/java/org/waarp/openr66/protocol/localhandler/ServerActions.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1264,7 +1264,8 @@ private void shutdownLocalChannel() {
12641264
if (time == 0) {
12651265
logger.info("Will close networkChannel {}", ncr.nbLocalChannels());
12661266
NetworkTransaction.shuttingDownNetworkChannel(ncr);
1267-
NetworkTransaction.shuttingdownNetworkChannelsPerHostID(ncr.getHostId());
1267+
NetworkTransaction
1268+
.shuttingdownNetworkChannelsPerHostID(ncr.getHostId());
12681269
}
12691270
} finally {
12701271
ncr.unlockNetwork();

WaarpR66/src/main/java/org/waarp/openr66/protocol/localhandler/packet/DataPacket.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121

2222
import io.netty.buffer.ByteBuf;
2323
import io.netty.buffer.ByteBufAllocator;
24-
import io.netty.buffer.Unpooled;
2524
import org.waarp.common.digest.FilesystemBasedDigest;
2625
import org.waarp.common.logging.WaarpLogger;
2726
import org.waarp.common.logging.WaarpLoggerFactory;
@@ -123,7 +122,7 @@ public void createAllBuffers(final LocalChannelReference lcr,
123122

124123
@Override
125124
public void createEnd(final LocalChannelReference lcr) {
126-
end = Unpooled.wrappedBuffer(key);
125+
end = WaarpNettyUtil.wrappedBuffer(key);
127126
}
128127

129128
@Override
@@ -137,7 +136,7 @@ public void createMiddle(final LocalChannelReference lcr) {
137136
if (dataRecv != null) {
138137
middle = dataRecv;
139138
} else {
140-
middle = Unpooled.wrappedBuffer(data);
139+
middle = WaarpNettyUtil.wrappedBuffer(data);
141140
}
142141
}
143142

WaarpR66/src/main/java/org/waarp/openr66/protocol/localhandler/packet/RequestPacket.java

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,11 @@
2121

2222
import com.fasterxml.jackson.databind.node.ObjectNode;
2323
import io.netty.buffer.ByteBuf;
24-
import io.netty.buffer.Unpooled;
2524
import org.waarp.common.json.JsonHandler;
2625
import org.waarp.common.logging.WaarpLogger;
2726
import org.waarp.common.logging.WaarpLoggerFactory;
27+
import org.waarp.common.utility.WaarpNettyUtil;
28+
import org.waarp.common.utility.WaarpStringUtils;
2829
import org.waarp.openr66.context.ErrorCode;
2930
import org.waarp.openr66.protocol.configuration.Configuration;
3031
import org.waarp.openr66.protocol.configuration.PartnerConfiguration;
@@ -365,7 +366,8 @@ public void createAllBuffers(final LocalChannelReference lcr,
365366
@Override
366367
public void createEnd(final LocalChannelReference lcr) {
367368
if (transferInformation != null) {
368-
end = Unpooled.wrappedBuffer(transferInformation.getBytes());
369+
end = WaarpNettyUtil
370+
.wrappedBuffer(transferInformation.getBytes(WaarpStringUtils.UTF8));
369371
}
370372
}
371373

@@ -380,13 +382,13 @@ public void createHeader(final LocalChannelReference lcr)
380382
final ObjectNode node = JsonHandler.createObjectNode();
381383
JsonHandler.setValue(node, FIELDS.rule, rulename);
382384
JsonHandler.setValue(node, FIELDS.mode, mode);
383-
header =
384-
Unpooled.wrappedBuffer(JsonHandler.writeAsString(node).getBytes());
385+
header = WaarpNettyUtil.wrappedBuffer(
386+
JsonHandler.writeAsString(node).getBytes(WaarpStringUtils.UTF8));
385387
} else {
386-
header = Unpooled.wrappedBuffer(rulename.getBytes(),
387-
PartnerConfiguration.BLANK_SEPARATOR_FIELD
388-
.getBytes(),
389-
Integer.toString(mode).getBytes());
388+
header = WaarpNettyUtil.wrappedBuffer(rulename.getBytes(),
389+
PartnerConfiguration.BLANK_SEPARATOR_FIELD
390+
.getBytes(),
391+
Integer.toString(mode).getBytes());
390392
}
391393
}
392394

@@ -408,11 +410,14 @@ public void createMiddle(final LocalChannelReference lcr)
408410
JsonHandler.setValue(node, FIELDS.length, originalSize);
409411
// Add limit if specified
410412
JsonHandler.setValue(node, FIELDS.limit, limit);
411-
middle = Unpooled
412-
.wrappedBuffer(away, JsonHandler.writeAsString(node).getBytes());
413+
middle = WaarpNettyUtil.wrappedBuffer(away,
414+
JsonHandler.writeAsString(node)
415+
.getBytes(
416+
WaarpStringUtils.UTF8));
413417
} else {
414-
middle = Unpooled
415-
.wrappedBuffer(away, filename.getBytes(), separator.getBytes(),
418+
middle = WaarpNettyUtil
419+
.wrappedBuffer(away, filename.getBytes(WaarpStringUtils.UTF8),
420+
separator.getBytes(),
416421
Integer.toString(blocksize).getBytes(),
417422
separator.getBytes(),
418423
Integer.toString(rank).getBytes(),

WaarpR66/src/test/java/org/waarp/openr66/protocol/it/ScenarioBaseLoop.java

Lines changed: 171 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -323,16 +323,49 @@ public static int startServer(String serverConfig) throws Exception {
323323
*/
324324
@AfterClass
325325
public static void tearDownAfterClass() throws Exception {
326+
if (NUMBER_FILES == -1) {
327+
Configuration.configuration.setTimeoutCon(100);
328+
WaarpLoggerFactory.setLogLevel(WaarpLogLevel.ERROR);
329+
for (int pid : PIDS) {
330+
Processes.kill(pid, true);
331+
}
332+
tearDownAfterClassClient();
333+
tearDownAfterClassMinimal();
334+
tearDownAfterClassServer();
335+
return;
336+
}
326337
CloseableHttpClient httpClient = null;
338+
int max = SystemPropertyUtil.get(IT_LONG_TEST, false)? 60 : 20;
339+
if (max < NUMBER_FILES) {
340+
max = NUMBER_FILES * 3;
341+
}
342+
int totalTransfers = max;
343+
int nb = 0;
344+
int every10sec = 10;
345+
HttpGet request =
346+
new HttpGet("http://127.0.0.1:8098/v2/transfers?limit=100000");
347+
final long startTime = System.currentTimeMillis();
327348
try {
328349
httpClient = HttpClientBuilder.create().setConnectionManagerShared(true)
329350
.disableAutomaticRetries().build();
330-
HttpGet request =
331-
new HttpGet("http://127.0.0.1:8098/v2/transfers?limit=1000");
332351
CloseableHttpResponse response = null;
333-
int nb = 0;
334-
int every10sec = 10;
335-
int max = SystemPropertyUtil.get(IT_LONG_TEST, false)? 60 : 20;
352+
try {
353+
response = httpClient.execute(request);
354+
assertEquals(200, response.getStatusLine().getStatusCode());
355+
String content = EntityUtils.toString(response.getEntity());
356+
ObjectNode node = JsonHandler.getFromString(content);
357+
if (node != null) {
358+
JsonNode number = node.findValue("totalResults");
359+
int newNb = number.asInt();
360+
max += newNb;
361+
totalTransfers = max;
362+
logger.warn("Found {} transfers", newNb);
363+
}
364+
} finally {
365+
if (response != null) {
366+
response.close();
367+
}
368+
}
336369
while (nb < max) {
337370
try {
338371
response = httpClient.execute(request);
@@ -363,7 +396,12 @@ public static void tearDownAfterClass() throws Exception {
363396
httpClient.close();
364397
}
365398
}
399+
final long stopTime = System.currentTimeMillis();
400+
totalTransfers -= nb;
401+
logger.warn("Duration {} for {} item so {} items/s", (stopTime - startTime) / 1000.0, totalTransfers,
402+
totalTransfers / ((stopTime - startTime) / 1000.0));
366403
Configuration.configuration.setTimeoutCon(100);
404+
WaarpLoggerFactory.setLogLevel(WaarpLogLevel.ERROR);
367405
for (int pid : PIDS) {
368406
Processes.kill(pid, true);
369407
}
@@ -388,7 +426,7 @@ private void checkMemory() {
388426
Runtime runtime = Runtime.getRuntime();
389427
long newUsedMemory = runtime.totalMemory() - runtime.freeMemory();
390428
if (newUsedMemory > MAX_USED_MEMORY) {
391-
logger.warn("Used Memory > 2GB {} {}", usedMemory / 1048576.0,
429+
logger.info("Used Memory > 2GB {} {}", usedMemory / 1048576.0,
392430
newUsedMemory / 1048576.0);
393431
}
394432
}
@@ -472,6 +510,11 @@ private void testBigTransfer(boolean limit, String serverName, boolean direct,
472510
@Test
473511
public void test01_LoopBigSendsSyncNoLimit()
474512
throws IOException, InterruptedException {
513+
if (SystemPropertyUtil.get(IT_LONG_TEST, false)) {
514+
NUMBER_FILES = 4;
515+
} else {
516+
NUMBER_FILES = 2;
517+
}
475518
logger.warn("Start {} {}", Processes.getCurrentMethodName(), NUMBER_FILES);
476519
testBigTransfer(false, "server2", true, false, 1024 * 500 * 1024);
477520
testBigTransfer(false, "server2", true, false, 1024 * 1024 * 1024);
@@ -485,6 +528,11 @@ public void test01_LoopBigSendsSyncNoLimit()
485528
@Test
486529
public void test02_LoopBigSendsSyncSslNoLimit()
487530
throws IOException, InterruptedException {
531+
if (SystemPropertyUtil.get(IT_LONG_TEST, false)) {
532+
NUMBER_FILES = 2;
533+
} else {
534+
NUMBER_FILES = 1;
535+
}
488536
logger.warn("Start {} {}", Processes.getCurrentMethodName(), NUMBER_FILES);
489537
testBigTransfer(false, "server2-ssl", true, false, 1024 * 501 * 1024);
490538
if (SystemPropertyUtil.get(IT_LONG_TEST, false)) {
@@ -493,6 +541,123 @@ public void test02_LoopBigSendsSyncSslNoLimit()
493541
logger.warn("End {}", Processes.getCurrentMethodName());
494542
}
495543

544+
@Test
545+
public void test03_LoopBigSendsSyncSslNoLimit()
546+
throws IOException, InterruptedException {
547+
if (SystemPropertyUtil.get(IT_LONG_TEST, false)) {
548+
NUMBER_FILES = 700;
549+
} else {
550+
NUMBER_FILES = -1;
551+
logger.warn("Test disabled without IT_LONG_TEST");
552+
Assume.assumeTrue("If the Long term tests are allowed",
553+
SystemPropertyUtil.get(IT_LONG_TEST, false));
554+
return;
555+
}
556+
logger.warn("Start {} {}", Processes.getCurrentMethodName(), NUMBER_FILES);
557+
int limit = 700;
558+
int middleSize = 360 - (limit / 2);
559+
560+
Assume.assumeNotNull(networkTransaction);
561+
Configuration.configuration.changeNetworkLimit(0, 0, 0, 0, 1000);
562+
File baseDir = new File("/tmp/R66/scenario_big_file_limitbdw/R1/out/");
563+
for (int i = 0; i < limit; i++) {
564+
int size = (middleSize + i) * 1024;
565+
File fileOut = new File(baseDir, "hello" + size);
566+
final File outHello = generateOutFile(fileOut.getAbsolutePath(), size);
567+
}
568+
logger.warn("End of file creations");
569+
long timestart = System.currentTimeMillis();
570+
R66Future[] futures = new R66Future[limit];
571+
for (int i = 0; i < limit; i++) {
572+
int size = (middleSize + i) * 1024;
573+
final R66Future future = new R66Future(true);
574+
futures[i] = future;
575+
final TestTransferNoDb transaction =
576+
new TestTransferNoDb(future, "server2-ssl", "hello" + size, "loop",
577+
"Test Loop Send", true, BLOCK_SIZE,
578+
DbConstantR66.ILLEGALVALUE,
579+
networkTransaction);
580+
transaction.setNormalInfoAsWarn(false);
581+
transaction.run();
582+
}
583+
for (int i = 0; i < limit; i++) {
584+
futures[i].awaitOrInterruptible();
585+
assertTrue(futures[i].isSuccess());
586+
}
587+
//logger.info("Runner: {}", future.getRunner());
588+
long timestop = System.currentTimeMillis();
589+
logger.warn("Direct {}, Recv {}, LimitBandwidth {} " +
590+
"({} seconds, {} MBPS vs {} " +
591+
"and {}) of size {} with block size {}", true, false, limit,
592+
(timestop - timestart) / 1000,
593+
limit * 180*1024 / 1000.0 / (timestop - timestart),
594+
Configuration.configuration.getServerGlobalReadLimit() /
595+
1000000.0,
596+
Configuration.configuration.getServerChannelReadLimit() /
597+
1000000.0, limit *180*1024, BLOCK_SIZE);
598+
checkMemory();
599+
logger.warn("End {}", Processes.getCurrentMethodName());
600+
}
601+
602+
603+
@Test
604+
public void test04_LoopBigSendsSyncNoLimit()
605+
throws IOException, InterruptedException {
606+
if (SystemPropertyUtil.get(IT_LONG_TEST, false)) {
607+
NUMBER_FILES = 700;
608+
} else {
609+
NUMBER_FILES = -1;
610+
logger.warn("Test disabled without IT_LONG_TEST");
611+
Assume.assumeTrue("If the Long term tests are allowed",
612+
SystemPropertyUtil.get(IT_LONG_TEST, false));
613+
return;
614+
}
615+
logger.warn("Start {} {}", Processes.getCurrentMethodName(), NUMBER_FILES);
616+
int limit = 700;
617+
int middleSize = 360 - (limit / 2);
618+
619+
Assume.assumeNotNull(networkTransaction);
620+
Configuration.configuration.changeNetworkLimit(0, 0, 0, 0, 1000);
621+
File baseDir = new File("/tmp/R66/scenario_big_file_limitbdw/R1/out/");
622+
for (int i = 0; i < limit; i++) {
623+
int size = (middleSize + i) * 1024;
624+
File fileOut = new File(baseDir, "hello" + size);
625+
final File outHello = generateOutFile(fileOut.getAbsolutePath(), size);
626+
}
627+
logger.warn("End of file creations");
628+
long timestart = System.currentTimeMillis();
629+
R66Future[] futures = new R66Future[limit];
630+
for (int i = 0; i < limit; i++) {
631+
int size = (middleSize + i) * 1024;
632+
final R66Future future = new R66Future(true);
633+
futures[i] = future;
634+
final TestTransferNoDb transaction =
635+
new TestTransferNoDb(future, "server2", "hello" + size, "loop",
636+
"Test Loop Send", true, BLOCK_SIZE,
637+
DbConstantR66.ILLEGALVALUE,
638+
networkTransaction);
639+
transaction.setNormalInfoAsWarn(false);
640+
transaction.run();
641+
}
642+
for (int i = 0; i < limit; i++) {
643+
futures[i].awaitOrInterruptible();
644+
assertTrue(futures[i].isSuccess());
645+
}
646+
//logger.info("Runner: {}", future.getRunner());
647+
long timestop = System.currentTimeMillis();
648+
logger.warn("Direct {}, Recv {}, LimitBandwidth {} " +
649+
"({} seconds, {} MBPS vs {} " +
650+
"and {}) of size {} with block size {}", true, false, limit,
651+
(timestop - timestart) / 1000,
652+
limit * 180*1024 / 1000.0 / (timestop - timestart),
653+
Configuration.configuration.getServerGlobalReadLimit() /
654+
1000000.0,
655+
Configuration.configuration.getServerChannelReadLimit() /
656+
1000000.0, limit *180*1024, BLOCK_SIZE);
657+
checkMemory();
658+
logger.warn("End {}", Processes.getCurrentMethodName());
659+
}
660+
496661
private void waitForAllDone(DbTaskRunner runner) {
497662
while (true) {
498663
try {

0 commit comments

Comments
 (0)