/** * This software is GPLv2. * Take a look at the LICENSE file for more info. */ package de.tu.dresden.dud.dc.WorkCycle; import java.util.LinkedHashSet; import org.apache.log4j.Logger; import de.tu.dresden.dud.dc.Connection; import de.tu.dresden.dud.dc.ManagementMessage.ManagementMessageAdd; /** * A round represents the smallest step in a DC / DC+ work cycle. * * Each round belongs to a work cycle and has a unique round number. It * logically consists of each participant generating it's local sum, sending it * to the server and receiving the global sum. * * @author klobs * */ public class WorkCycleRound extends WorkCycle { // Logging private static Logger log = Logger.getLogger(WorkCycleRound.class); private int roundNumber = 0; private Thread roundTimeoutController = null; /** * Each round belongs to a work cycle and has a unique round number. * * @param roundNumber unique round number to identify the round * @param r the {@link WorkCycleSending} which the round belongs to. */ WorkCycleRound(int roundNumber, WorkCycleSending r){ this.expectedConnections = (LinkedHashSet<Connection>) r.getConnections().clone(); // TODO can we find a less expansive possibility here? this.workCycleSending = r; this.roundNumber = roundNumber; } /** * This method is called on server side after an * {@link ManagementMessageAdd} arrived over the {@link Connection}. * * This method is responsible for collecting all expected add messages, and * as soon as all expected add messages arrived, notify the observers (which * is usually only the "parent" {@link WorkCycleSending}) that the global sum * can be calculated. * * @param c * the connection over which the ADD message arrived * @param m * the management message that arrived. */ public synchronized void addMessageArrived(Connection c, ManagementMessageAdd m){ if (payloads.size() == 0){ roundTimeoutController = new Thread( new WorkCycleRoundTimeoutController(workCycleSending .getAssocWorkCycleManager() .getRealtimeMessageTimeout(), this), "roundTimeoutChecker_" + this.getWorkCycleNumber() + ":" + this.getRoundNumber()); roundTimeoutController.start(); } payloads.add(m.getPayload()); expectedConnections.remove(c); confirmedConnections.add(c); log.debug( "New ADD message for work cycle "+ m.getWorkCycleNumber() +" and round "+ m.getRoundNumber() +" is being processed. There are now " + confirmedConnections.size() + " confirmed messages and " + expectedConnections.size() + " more expected messages"); checkWhetherToAddUpAndIfYesDoSo(); } public void checkWhetherToAddUpAndIfYesDoSo(){ if (expectedConnections.size() == 0) { if(roundTimeoutController != null){ if(roundTimeoutController.getState() != Thread.State.TERMINATED){ roundTimeoutController.interrupt(); } } log.debug(" there are no more new messages expected. ADDing notification"); setChanged(); notifyObservers(WorkCycle.WC_ROUND_ADDUP); } } /** * Standard getter * @return The unique round number. */ public int getRoundNumber(){ return this.roundNumber; } public Thread getTimeoutController(){ return roundTimeoutController; } }