/******************************************************************************* * gMix open source project - https://svs.informatik.uni-hamburg.de/gmix/ * Copyright (C) 2014 SVS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. *******************************************************************************/ package staticContent.evaluation.loadGenerator.applicationLevelTraffic.requestReply; import java.io.IOException; import java.util.Arrays; import java.util.Vector; import staticContent.evaluation.loadGenerator.LoadGenerator; import staticContent.framework.config.Settings; import staticContent.framework.util.IOTester; import staticContent.framework.util.Util; public class ALRR_ReplyReceiver extends Thread { private Vector<ApplicationLevelReplyReceivedObserver> observers; private ALRR_ClientWrapper[] clientsArray; public ALRR_ReplyReceiver(ALRR_ClientWrapper[] clientsArray, Settings settings) { this.clientsArray = clientsArray; this.observers = new Vector<ApplicationLevelReplyReceivedObserver>(); ALRR_ClientWrapper.init(settings.getPropertyAsInt("GLOBAL_EXPECTED_NUMBER_OF_USERS")); } public void registerObserver(ApplicationLevelReplyReceivedObserver observer) { synchronized (observers) { this.observers.add(observer); } } @Override public void run() { while (true) { // read replies... int ctr = 0; for (ALRR_ClientWrapper cw: clientsArray) { // ...for each client try { int available = cw.inputStream.available(); if ((cw.headerRead && available > 0) || (!cw.headerRead && available >= 4)) { // if (enough) data available ctr++; // read available data: int len = cw.headerRead ? available: (available-(available%4));// don't read half headers byte[] arrivedData = new byte[len]; int read = cw.inputStream.read(arrivedData); assert read == arrivedData.length: ""+read; // assured by mix io-streams System.out.println("" +this +": received (client): " +Util.toHex(arrivedData)); // TODO: remove if (LoadGenerator.VALIDATE_IO) IOTester.findInstance("reply-"+cw.identifier).addReceiveRecord(arrivedData); //if (read != arrivedData.length) // arrivedData = Util.split(read, arrivedData)[0]; // extract replies: byte[] remaining = arrivedData; ApplicationLevelMessage message; while (remaining != null) { // read transaction id if not yet done and load the current ApplicationLevelMessage-Instance: if (!cw.headerRead) { int transactionId = Util.byteArrayToInt(Arrays.copyOf(remaining, 4)); message = ALRR_ClientWrapper.activeTransactions.get(transactionId); assert message != null: "received a transaction id in a reply message that was never sent: " +transactionId; cw.currentTraceEntry = message; cw.headerRead = true; } else { message = cw.currentTraceEntry; } remaining = message.addReplyChunk(remaining); if (!message.needMoreReplyChunks()) { // reply now received completely // display stats: long delay = System.currentTimeMillis() - message.getAbsoluteSendTime(); System.out.println( "LOAD_GENERATOR: received reply (" + "transactionId: " +message.getTransactionId() +"; replySize: " +message.getReplySize() +"bytes" +"; delay: " +delay +"ms" +")" ); synchronized (observers) { for (ApplicationLevelReplyReceivedObserver observer: observers) observer.replyReceived(message); } cw.headerRead = false; cw.currentTraceEntry = null; } } } } catch (IOException e) { e.printStackTrace(); continue; } } if (ctr == 0) // TODO wait-notify? try {Thread.sleep(1);} catch (InterruptedException e) {e.printStackTrace();} } } }