/* *************************************************************************************** * Copyright (C) 2006 EsperTech, Inc. All rights reserved. * * http://www.espertech.com/esper * * http://www.espertech.com * * ---------------------------------------------------------------------------------- * * The software in this package is published under the terms of the GPL license * * a copy of which has been included with this distribution in the license.txt file. * *************************************************************************************** */ package com.espertech.esper.example.benchmark.client; import com.espertech.esper.example.benchmark.MarketData; import com.espertech.esper.example.benchmark.Symbols; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; /** * A thread that sends market data (symbol, volume, price) at the target rate to the remote host * * @author Alexandre Vasseur http://avasseur.blogspot.com */ public class MarketClient extends Thread { private Client client; private MarketData[] market; public MarketClient(Client client) { this.client = client; market = new MarketData[Symbols.SYMBOLS.length]; for (int i = 0; i < market.length; i++) { market[i] = new MarketData(Symbols.SYMBOLS[i], Symbols.nextPrice(10), Symbols.nextVolume(10)); } System.out.printf("MarketData with %d symbols\n", market.length); } public void run() { SocketChannel socketChannel = null; try { socketChannel = SocketChannel.open(new InetSocketAddress(client.host, client.port)); System.out.printf("Client connected to %s:%d, rate %d msg/s\n", client.host, client.port, client.rate); } catch (IOException e) { throw new RuntimeException(e); } MarketData[] market = this.market; int eventPer50ms = client.rate / 20; int tickerIndex = 0; int countLast5s = 0; int sleepLast5s = 0; long lastThroughputTick = System.currentTimeMillis(); try { ByteBuffer byteBuffer = ByteBuffer.allocateDirect(MarketData.SIZE / 8); do { long ms = System.currentTimeMillis(); for (int i = 0; i < eventPer50ms; i++) { tickerIndex = tickerIndex % Symbols.SYMBOLS.length; MarketData md = market[tickerIndex++]; md.setPrice(Symbols.nextPrice(md.getPrice())); md.setVolume(Symbols.nextVolume(10)); byteBuffer.clear(); md.toByteBuffer(byteBuffer); byteBuffer.flip(); socketChannel.write(byteBuffer); countLast5s++; // info if (System.currentTimeMillis() - lastThroughputTick > 5 * 1E3) { System.out.printf("Sent %d in %d(ms) avg ns/msg %.0f(ns) avg %d(msg/s) sleep %d(ms)\n", countLast5s, System.currentTimeMillis() - lastThroughputTick, (float) 1E6 * countLast5s / (System.currentTimeMillis() - lastThroughputTick), countLast5s / 5, sleepLast5s ); countLast5s = 0; sleepLast5s = 0; lastThroughputTick = System.currentTimeMillis(); } } // rate adjust if (System.currentTimeMillis() - ms < 50) { // lets avoid sleeping if == 1ms, lets account 3ms for interrupts long sleep = Math.max(1, 50 - (System.currentTimeMillis() - ms) - 3); sleepLast5s += sleep; Thread.sleep(sleep); } } while (true); } catch (Throwable t) { t.printStackTrace(); System.err.println("Error sending data to server. Did server disconnect?"); } } }