io.fixprotocol.silverflash.transport.TlsTcpTransportBenchmark Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of benchmark Show documentation
Show all versions of benchmark Show documentation
Microbenchmarks for FIXP engine implementation
The newest version!
/**
* Copyright 2015 FIX Protocol Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package io.fixprotocol.silverflash.transport;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.Selector;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.util.Arrays;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import org.openjdk.jmh.annotations.AuxCounters;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.TearDown;
import io.fixprotocol.silverflash.ExceptionConsumer;
import io.fixprotocol.silverflash.auth.Crypto;
import io.fixprotocol.silverflash.buffer.BufferSupplier;
import io.fixprotocol.silverflash.buffer.SingleBufferSupplier;
import io.fixprotocol.silverflash.transport.IOReactor;
import io.fixprotocol.silverflash.transport.TlsTcpAcceptor;
import io.fixprotocol.silverflash.transport.TlsTcpConnectorTransport;
import io.fixprotocol.silverflash.transport.Transport;
import io.fixprotocol.silverflash.transport.TransportConsumer;
import io.fixprotocol.silverflash.util.platform.AffinityThreadFactory;
@State(Scope.Benchmark)
public class TlsTcpTransportBenchmark {
@Param({"1", "2", "4", "8"})
public int batchSize;
private class InjectorConsumer implements TransportConsumer {
@Override
public void accept(ByteBuffer t) {
// do nothing
}
@Override
public void connected() {
startSignal.countDown();
}
@Override
public void disconnected() {
// do nothing
}
}
private class Reflector implements TransportConsumer {
private final Transport transport;
public Reflector(Transport transport) {
this.transport = transport;
}
@Override
public void accept(ByteBuffer inbound) {
inbound.rewind();
try {
transport.write(inbound);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public void connected() {
// do nothing
}
@Override
public void disconnected() {
// do nothing
}
}
private static final InetSocketAddress serverAddress = new InetSocketAddress(
InetAddress.getLoopbackAddress(), 7545);
private static AffinityThreadFactory threadFactory;
private char[] storePassphrase = "password".toCharArray();
@Param({"128", "256", "1024"})
public int bufferSize;
private BufferSupplier clientBuffers;
private TlsTcpConnectorTransport clientTransport;
private IOReactor serverIOReactor;
private IOReactor clientIOReactor;
private byte[] message;
private ByteBuffer[] srcs;
private TlsTcpAcceptor tcpAcceptor;
private CountDownLatch startSignal;
private Function transportWrapper = new Function() {
public Transport apply(Transport transport) {
try {
transport.open(
new SingleBufferSupplier(ByteBuffer.allocateDirect(bufferSize * batchSize * 64).order(
ByteOrder.nativeOrder())), new Reflector(transport)).get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
return transport;
}
};
@TearDown
public void detroyTestEnvironment() throws IOException, InterruptedException {
clientTransport.close();
tcpAcceptor.close();
serverIOReactor.close();
clientIOReactor.close();
}
@Setup
public void initTestEnvironment() throws IOException, InterruptedException, ExecutionException,
GeneralSecurityException {
startSignal = new CountDownLatch(1);
message = new byte[bufferSize];
Arrays.fill(message, (byte) 'x');
srcs = new ByteBuffer[batchSize];
for (int i = 0; i < batchSize; ++i) {
srcs[i] = ByteBuffer.allocateDirect(bufferSize).order(ByteOrder.nativeOrder());
}
threadFactory = new AffinityThreadFactory(true, true, "benchmark");
KeyStore ksKeys = Crypto.createKeyStore();
Crypto
.addKeyCertificateEntry(ksKeys, "exchange", "CN=trading, O=myorg, C=US", storePassphrase);
KeyStore ksTrust = Crypto.createKeyStore();
Crypto.addKeyCertificateEntry(ksTrust, "customer", "CN=Trader1, O=SomeFCM, C=US",
storePassphrase);
ExceptionConsumer exceptionConsumer = System.err::println;
serverIOReactor = new IOReactor(threadFactory, exceptionConsumer);
serverIOReactor.open().get();
tcpAcceptor =
createTcpAcceptor(serverIOReactor.getSelector(), serverAddress, ksKeys, ksTrust,
storePassphrase, transportWrapper);
tcpAcceptor.open().get();
clientIOReactor = new IOReactor(threadFactory, exceptionConsumer);
clientIOReactor.open().get();
clientBuffers =
new SingleBufferSupplier(ByteBuffer.allocate(bufferSize * batchSize * 64).order(
ByteOrder.nativeOrder()));
clientTransport =
createClientTcpTransport(clientIOReactor.getSelector(), serverAddress, ksTrust, ksKeys,
storePassphrase);
clientTransport.open(clientBuffers, new InjectorConsumer());
startSignal.await(1000L, TimeUnit.MILLISECONDS);
// client gets accepted signal before server transport is fully
// constructed
Thread.sleep(500L);
}
private TlsTcpAcceptor createTcpAcceptor(Selector selector, SocketAddress localAddress,
KeyStore keystore, KeyStore truststore, char[] storePassphrase,
Function transportWrapper) {
return new TlsTcpAcceptor(selector, localAddress, keystore, truststore, storePassphrase,
transportWrapper);
}
private TlsTcpConnectorTransport createClientTcpTransport(Selector selector,
InetSocketAddress remoteAddress, KeyStore ksKeys, KeyStore ksTrust, char[] storePassphrase) {
return new TlsTcpConnectorTransport(selector, remoteAddress, ksKeys, ksTrust, storePassphrase);
}
@AuxCounters
@State(Scope.Thread)
public static class Counters {
public int failed;
public int succeeded;
@Setup(Level.Iteration)
public void clean() {
failed = 0;
succeeded = 0;
}
}
@Benchmark
public void inject(Counters counters) throws IOException {
for (int i = 0; i < batchSize; i++) {
srcs[i].clear();
srcs[i].put(message);
}
long bytesWritten = clientTransport.write(srcs);
if (bytesWritten == 0) {
counters.failed++;
} else {
counters.succeeded++;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy