/******************************************************************************* * 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.simulator.core.networkComponent; import staticContent.evaluation.simulator.Simulator; import staticContent.evaluation.simulator.annotations.property.StringSimulationProperty; import staticContent.evaluation.simulator.core.event.Event; import staticContent.evaluation.simulator.core.event.EventExecutor; import staticContent.evaluation.simulator.core.event.SimulationEvent; import staticContent.evaluation.simulator.core.message.EndToEndMessage; import userGeneratedContent.simulatorPlugIns.pluginRegistry.StatisticsType; public abstract class AbstractServer implements EventExecutor { private DistantProxy distantProxy; @StringSimulationProperty( key = "COMMUNICATION_MODE", name = "Communication mode", inject = "0:SIMULATION,Simulation", global = true, isStatic = true, possibleValues = "SIMPLEX,SIMPLEX_WITH_FEEDBACK,DUPLEX,SIMPLEX_REPLY" ) String commMode; protected boolean SIMULATE_REPLY_CHANNEL; protected boolean UNLIMITED_BANDWIDTH; protected Simulator simulator; // TODO: update comments protected AbstractServer(DistantProxy distantProxy) { this.distantProxy = distantProxy; this.SIMULATE_REPLY_CHANNEL = Simulator.settings.getProperty("COMMUNICATION_MODE").equals("SIMPLEX_REPLY") || Simulator.settings.getProperty("COMMUNICATION_MODE").equals("DUPLEX"); this.UNLIMITED_BANDWIDTH = Simulator.settings.getProperty("TYPE_OF_DELAY_BOX").equals("NO_DELAY_BOX"); this.simulator = Simulator.getSimulator(); } public static AbstractServer getInstance(DistantProxy distantProxy) { return new Server(distantProxy); } /** * called when a message from a client has reached this server. * subclasses can use the method sendReplyIn(long delay, EndToEndMessage * reply) in their implementation of this method, to send one or more * replies to the client. * * example: * if (simulateReplyChannel) { * Transaction at = message.payload; * float[] replyDelays = at.getDistinctReplyDelays(); * int[] replySizes = at.getDistinctReplySizes(); * if (replySizes == null || replySizes.length == 0) { // no reply * return; * } else { // create and schedule replies: * for (int i=0; i<replySizes.length; i++) { * long delay = Transaction.delayToMilliSec(replyDelays[i]); * EndToEndMessage reply = message.createReplyForThisMessage(at, replySizes[i]); * sendReplyIn(delay, reply); * } * } * } * * @param message */ public abstract void incomingMessage(EndToEndMessage message); /** * can be used by subclasses to send a reply to a client (the subclass must * have received a message via incomingMessage(EndToEndMessage message) * before this method can be called) * * example: * EndToEndMessage reply = message.createReplyForThisMessage(at, 100); * sendReplyIn(10, reply); * @param message */ public void sendReplyIn(long delay, EndToEndMessage reply) { Event sendReplyEvent = new Event(this, Simulator.getNow() + delay, ServerEvent.TIMEOUT, reply); //System.out.println("scheduling sendMessage() for transaction " +((EndToEndMessage)sendReplyEvent.getAttachment()).getPayload().getTransactionId() +" (now: " +Simulator.getNow() +")"); simulator.scheduleEvent(sendReplyEvent, this); } private void sendMessage(EndToEndMessage eteMessage) { if (SIMULATE_REPLY_CHANNEL) { distantProxy.statistics.increment(eteMessage.transportMessage.getLength(), StatisticsType.SUM_DISTANTPROXY_DATAVOLUME_SENDANDRECEIVE); distantProxy.requestAnswered(eteMessage.transportMessage); } } @Override public void executeEvent(Event event) { if (event.getEventType() instanceof ServerEvent && event.getEventType() == ServerEvent.TIMEOUT) { //System.out.println("calling sendMessage() for transaction " +((EndToEndMessage)event.getAttachment()).getPayload().getTransactionId() +" (now: " +Simulator.getNow() +", object-ref: " +event.getAttachment() +"), size: " +((EndToEndMessage)event.getAttachment()).transportMessage.getLength()); sendMessage((EndToEndMessage)event.getAttachment()); } else { throw new RuntimeException("ERROR: ServerSimulator received wrong Event: " +event.getEventType().toString()); } } public enum ServerEvent implements SimulationEvent { TIMEOUT; } }