From 2cbf4c64a23ed9bf2da7942c0ae765f07e038697 Mon Sep 17 00:00:00 2001
From: Stefan Derkits <stefan@derkits.at>
Date: Tue, 11 Jun 2013 11:26:32 +0200
Subject: [PATCH] moved DelayedApps List to Abstract scheduler, remove started
 apps from delayed apps list, added some TODOs in SchedB

---
 .../tuwien/lsdc/sched/AbstractScheduler.java  | 92 +++++++++----------
 src/at/ac/tuwien/lsdc/sched/SchedulerB.java   | 78 +++++++---------
 2 files changed, 77 insertions(+), 93 deletions(-)

diff --git a/src/at/ac/tuwien/lsdc/sched/AbstractScheduler.java b/src/at/ac/tuwien/lsdc/sched/AbstractScheduler.java
index 7e3984e..2305c3e 100644
--- a/src/at/ac/tuwien/lsdc/sched/AbstractScheduler.java
+++ b/src/at/ac/tuwien/lsdc/sched/AbstractScheduler.java
@@ -2,6 +2,7 @@ package at.ac.tuwien.lsdc.sched;
 
 import java.io.File;
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.SortedMap;
 import java.util.TreeMap;
@@ -42,23 +43,23 @@ public abstract class AbstractScheduler {
 	protected CSVLogger logger;
 	protected VMType vmType;
 
+	// List of Apps that were delayed due to not enough free resources.
+	protected ArrayList<Application> delayedApps;
+
 	/**
-	 * this map saves the following Type of Events: start of an Application, end
-	 * of an Application(start outSourced, end outSourced, start inSourced, end
-	 * inSourced)
+	 * this map saves the following Type of Events: start of an Application, end of an
+	 * Application(start outSourced, end outSourced, start inSourced, end inSourced)
 	 */
 	protected SortedMap<Long, LinkedList<SchedulerEvent>> eventMap;
 
 	/**
-	 * Scheduler has an internal Time "Abstraction" at every point in time it
-	 * checks for Events in his "EventList" and handles them (via the individual
-	 * scheduling algorithm)
+	 * Scheduler has an internal Time "Abstraction" at every point in time it checks for Events in
+	 * his "EventList" and handles them (via the individual scheduling algorithm)
 	 */
 	protected long currTime = 0;
 
 	/**
-	 * the timestamp at which the Scheduler is finished it is updated with every
-	 * added "EndEvent"
+	 * the timestamp at which the Scheduler is finished it is updated with every added "EndEvent"
 	 */
 	protected long endTime;
 
@@ -67,19 +68,20 @@ public abstract class AbstractScheduler {
 	 */
 	protected Federation federation;
 
-	public AbstractScheduler(int numPMs, int numCloudPartners, File schedulerLog, ScenarioType scenario)
-			throws IOException {
+	public AbstractScheduler(int numPMs, int numCloudPartners, File schedulerLog,
+			ScenarioType scenario) throws IOException {
 		manager = new MachineManager(numPMs);
 		this.schedulerLog = schedulerLog;
 		this.scenario = scenario;
 		eventMap = new TreeMap<Long, LinkedList<SchedulerEvent>>();
 		logger = new CSVLogger(schedulerLog);
 		federation = new Federation(numCloudPartners);
+		delayedApps = new ArrayList<Application>();
 	}
 
 	/**
-	 * Initialize Scheduler with Data from CSV CSV will be parsed and sent as
-	 * List<Application> to Scheduler
+	 * Initialize Scheduler with Data from CSV CSV will be parsed and sent as List<Application> to
+	 * Scheduler
 	 */
 	public ScenarioData initAndStart(LinkedList<Application> apps) {
 		for (Application app : apps) {
@@ -93,13 +95,10 @@ public abstract class AbstractScheduler {
 	}
 
 	/**
-	 * Insert a start event into the map, at timestamp when the application should
-	 * start
+	 * Insert a start event into the map, at timestamp when the application should start
 	 * 
-	 * @param timestamp
-	 *          the timestamp when the application should start
-	 * @param app
-	 *          the application to start
+	 * @param timestamp the timestamp when the application should start
+	 * @param app the application to start
 	 */
 	protected void insertStartEvent(long timestamp, Application app) {
 		SchedulerEvent evt = new SchedulerEvent(timestamp, EventType.startApplication, app);
@@ -114,16 +113,14 @@ public abstract class AbstractScheduler {
 	}
 
 	/**
-	 * Insert a start outsourced event into the map, at timestamp when the
-	 * application should start
+	 * Insert a start outsourced event into the map, at timestamp when the application should start
 	 * 
-	 * @param timestamp
-	 *          the timestamp when the application should start
-	 * @param app
-	 *          the application to start
+	 * @param timestamp the timestamp when the application should start
+	 * @param app the application to start
 	 */
 	protected void insertOutsourcedStartEvent(long timestamp, Application app) {
-		SchedulerEvent evt = new SchedulerEvent(timestamp, EventType.startOutsourcedApplication, app);
+		SchedulerEvent evt = new SchedulerEvent(timestamp, EventType.startOutsourcedApplication,
+				app);
 		if (!eventMap.containsKey(timestamp)) {
 			LinkedList<SchedulerEvent> list = new LinkedList<SchedulerEvent>();
 			list.add(evt);
@@ -135,13 +132,10 @@ public abstract class AbstractScheduler {
 	}
 
 	/**
-	 * Insert a stop event into the map, at timestamp when the application should
-	 * stop.
+	 * Insert a stop event into the map, at timestamp when the application should stop.
 	 * 
-	 * @param timestamp
-	 *          the timestamp when the application should stop
-	 * @param app
-	 *          the application to stop
+	 * @param timestamp the timestamp when the application should stop
+	 * @param app the application to stop
 	 */
 	protected void insertStopEvent(long timestamp, Application app) {
 		SchedulerEvent evt = new SchedulerEvent(timestamp, EventType.endApplication, app);
@@ -159,13 +153,10 @@ public abstract class AbstractScheduler {
 	}
 
 	/**
-	 * Insert a stop event into the map, at timestamp when the application should
-	 * stop.
+	 * Insert a stop event into the map, at timestamp when the application should stop.
 	 * 
-	 * @param timestamp
-	 *          the timestamp when the application should stop
-	 * @param app
-	 *          the application to stop
+	 * @param timestamp the timestamp when the application should stop
+	 * @param app the application to stop
 	 */
 	protected void insertOutsourcedStopEvent(long timestamp, Application app) {
 		SchedulerEvent evt = new SchedulerEvent(timestamp, EventType.endOutsourcedApplication, app);
@@ -183,8 +174,8 @@ public abstract class AbstractScheduler {
 	}
 
 	/**
-	 * Start the actual scheduling algorithm. Each scheduler will implement the
-	 * method handleEvents differently
+	 * Start the actual scheduling algorithm. Each scheduler will implement the method handleEvents
+	 * differently
 	 */
 	protected void startScheduling() {
 		while (true) {
@@ -206,22 +197,22 @@ public abstract class AbstractScheduler {
 	}
 
 	/**
-	 * this method is where the Scheduling Algorithm resides it reads the Events
-	 * (start & stop of applications)
+	 * this method is where the Scheduling Algorithm resides it reads the Events (start & stop of
+	 * applications)
 	 * 
-	 * @param events
-	 *          the events to be read and used by the scheduler
+	 * @param events the events to be read and used by the scheduler
 	 */
 	protected abstract void handleEvents(LinkedList<SchedulerEvent> events);
 
 	/**
-	 * Does the logging for each timestamp. It uses the CSVLogger to write
-	 * directly to the specific scheduler/scenario csv file
+	 * Does the logging for each timestamp. It uses the CSVLogger to write directly to the specific
+	 * scheduler/scenario csv file
 	 */
 	protected void doStateLogging() {
-		SchedulerData data = new SchedulerData(currTime, manager.getTotalRam(), manager.getTotalCpu(),
-				manager.getTotalSize(), manager.countCurrentlyRunningPMs(), manager.countCurrentlyRunningVMs(),
-				manager.getCurrentConsumption(), numCurrInSourced, numCurrOutSourced);
+		SchedulerData data = new SchedulerData(currTime, manager.getTotalRam(),
+				manager.getTotalCpu(), manager.getTotalSize(), manager.countCurrentlyRunningPMs(),
+				manager.countCurrentlyRunningVMs(), manager.getCurrentConsumption(),
+				numCurrInSourced, numCurrOutSourced);
 		totalConsumption += manager.getCurrentConsumption();
 		try {
 			logger.logSchedulerData(data);
@@ -236,8 +227,9 @@ public abstract class AbstractScheduler {
 	 * @return a ScenarioData Object that holds the values to be logged
 	 */
 	protected ScenarioData doEndLogging() {
-		return new ScenarioData(getSchedulerType(), scenario.toString(), manager.getTotalPMs(), manager.getTotalVMs(),
-				endTime, NumberUtils.roundDouble(totalConsumption), numTotalInSourced, numTotalOutSourced);
+		return new ScenarioData(getSchedulerType(), scenario.toString(), manager.getTotalPMs(),
+				manager.getTotalVMs(), endTime, NumberUtils.roundDouble(totalConsumption),
+				numTotalInSourced, numTotalOutSourced);
 	}
 
 	protected abstract String getSchedulerType();
diff --git a/src/at/ac/tuwien/lsdc/sched/SchedulerB.java b/src/at/ac/tuwien/lsdc/sched/SchedulerB.java
index b14540d..a14e27b 100644
--- a/src/at/ac/tuwien/lsdc/sched/SchedulerB.java
+++ b/src/at/ac/tuwien/lsdc/sched/SchedulerB.java
@@ -2,7 +2,6 @@ package at.ac.tuwien.lsdc.sched;
 
 import java.io.File;
 import java.io.IOException;
-import java.util.ArrayList;
 import java.util.LinkedList;
 
 import org.slf4j.Logger;
@@ -22,14 +21,12 @@ import at.ac.tuwien.lsdc.types.VirtualMachine.VMType;
 /**
  * Scheduler B.
  * 
- * Initial State: All PMs switched off. If an application arrives, try to modify
- * size, CPU and RAM of an existing VM to run the application. If no VM is
- * running, create a new one (start a new PM if necessary). If the application
- * has finished decrease the size, CPU and RAM of the VM. If no applications are
- * running on a VM, shut down the VM. If no VM is running on a PM, shut down the
- * PM. Try to get a maximum of utilization on every PM. Migration: Try to move
- * applications from VMs to other VMs to get a better utilization and to use
- * less PMs.
+ * Initial State: All PMs switched off. If an application arrives, try to modify size, CPU and RAM
+ * of an existing VM to run the application. If no VM is running, create a new one (start a new PM
+ * if necessary). If the application has finished decrease the size, CPU and RAM of the VM. If no
+ * applications are running on a VM, shut down the VM. If no VM is running on a PM, shut down the
+ * PM. Try to get a maximum of utilization on every PM. Migration: Try to move applications from VMs
+ * to other VMs to get a better utilization and to use less PMs.
  * 
  * @author jan
  * 
@@ -40,17 +37,10 @@ public class SchedulerB extends AbstractScheduler {
 	 */
 	private static final Logger LOG = LoggerFactory.getLogger(SchedulerB.class);
 
-	/**
-	 * List of Apps that were delayed due to not enough free resources. TODO: move
-	 * to abstractSched?
-	 */
-	private ArrayList<Application> delayedApps;
-
-	public SchedulerB(int numPMs, int numCloudPartners, File schedulerLog, ScenarioType scenario) throws IOException {
+	public SchedulerB(int numPMs, int numCloudPartners, File schedulerLog, ScenarioType scenario)
+			throws IOException {
 		super(numPMs, numCloudPartners, schedulerLog, scenario);
-
 		vmType = VMType.Resizable;
-		delayedApps = new ArrayList<Application>();
 	}
 
 	@Override
@@ -67,8 +57,7 @@ public class SchedulerB extends AbstractScheduler {
 	/**
 	 * handle running of outsourced apps.
 	 * 
-	 * @param events
-	 *          list of all events that happened in this timeslot.
+	 * @param events list of all events that happened in this timeslot.
 	 */
 	private void handleOutsourcedStartEvents(LinkedList<SchedulerEvent> events) {
 		for (SchedulerEvent evt : events) {
@@ -83,8 +72,7 @@ public class SchedulerB extends AbstractScheduler {
 	/**
 	 * handle stopping of outsourced apps.
 	 * 
-	 * @param events
-	 *          list of all events that happened in this timeslot.
+	 * @param events list of all events that happened in this timeslot.
 	 */
 	private void handleOutsourcedEndEvents(LinkedList<SchedulerEvent> events) {
 		for (SchedulerEvent evt : events) {
@@ -98,14 +86,17 @@ public class SchedulerB extends AbstractScheduler {
 	 * Check if we have any delayed apps. Try to launch them.
 	 */
 	private void runDelayedApps() {
-		ArrayList<Application> newDelayedApps = new ArrayList<Application>();
-		for (int i = 0; i < delayedApps.size(); i++) {
-			Application app = delayedApps.get(i);
+		// TODO: probably mostly the same code as handleStartEvents
+		// TOOD: (namely: use case: "start an application",do merge it
+		for (Application app : delayedApps) {
 			VirtualMachine vm = null;
 			for (PhysicalMachine pm : manager.getPMs()) {
-				vm = pm.getVirtualMachines().get((pm.getVirtualMachines().keySet().toArray(new Integer[0]))[0]);
+				// TODO: choose PM better to get better Utilization
+				vm = pm.getVirtualMachines().get(
+						(pm.getVirtualMachines().keySet().toArray(new Integer[0]))[0]);
 				try {
-					vm.resizeVM(vm.getSize() + app.getSize(), vm.getRAM() + app.getRam(), vm.getCPU() + app.getCpu());
+					vm.resizeVM(vm.getSize() + app.getSize(), vm.getRAM() + app.getRam(),
+							vm.getCPU() + app.getCpu());
 					break;
 				} catch (VMResizeException ex) {
 					vm = null;
@@ -113,7 +104,8 @@ public class SchedulerB extends AbstractScheduler {
 			}
 			if (vm == null) {
 				try {
-					vm = manager.startPhysicalMachine().startVirtualMachine(app.getSize(), app.getRam(), app.getCpu(), vmType);
+					vm = manager.startPhysicalMachine().startVirtualMachine(app.getSize(),
+							app.getRam(), app.getCpu(), vmType);
 				} catch (OutOfPMsException e) {
 					// LOG.error("failed to start PM.", e);
 					if (federation.askToOutsource(app)) {
@@ -126,8 +118,8 @@ public class SchedulerB extends AbstractScheduler {
 			vm.startApplication(app);
 			app.setRunningOn(vm);
 			insertStopEvent(currTime + app.getDuration(), app);
+			delayedApps.remove(app);
 		}
-		delayedApps = newDelayedApps;
 	}
 
 	/**
@@ -138,11 +130,9 @@ public class SchedulerB extends AbstractScheduler {
 	}
 
 	/**
-	 * Cleanup completed apps. Downsize VMs and if an VM becomes empty, shut down
-	 * VM + PM.
+	 * Cleanup completed apps. Downsize VMs and if an VM becomes empty, shut down VM + PM.
 	 * 
-	 * @param events
-	 *          list of all events that happened in this timeslot.
+	 * @param events list of all events that happened in this timeslot.
 	 */
 	protected void handleEndEvents(LinkedList<SchedulerEvent> events) {
 		LOG.debug("stopApps():" + events);
@@ -152,8 +142,8 @@ public class SchedulerB extends AbstractScheduler {
 				evt.getApp().setRunningOn(null);
 				vm.stopApplication(evt.getApp());
 				try {
-					vm.resizeVM(vm.getSize() - evt.getApp().getSize(), vm.getRAM() - evt.getApp().getRam(), vm.getCPU()
-							- evt.getApp().getCpu());
+					vm.resizeVM(vm.getSize() - evt.getApp().getSize(), vm.getRAM()
+							- evt.getApp().getRam(), vm.getCPU() - evt.getApp().getCpu());
 				} catch (VMResizeException e) {
 					// LOG.error("failed to resize VM: " + e.getVm(), e);
 				}
@@ -167,11 +157,10 @@ public class SchedulerB extends AbstractScheduler {
 	}
 
 	/**
-	 * Try to start all Apps. Upsize the VM, if not possible start another PM, if
-	 * not possible, delay start.
+	 * Try to start all Apps. Upsize the VM, if not possible start another PM, if not possible,
+	 * delay start.
 	 * 
-	 * @param events
-	 *          list of all events that happened in this timeslot.
+	 * @param events list of all events that happened in this timeslot.
 	 */
 	protected void handleStartEvents(LinkedList<SchedulerEvent> events) {
 		LOG.debug("startApps():" + events);
@@ -179,10 +168,12 @@ public class SchedulerB extends AbstractScheduler {
 			if (evt.getType() == EventType.startApplication) {
 				VirtualMachine vm = null;
 				for (PhysicalMachine pm : manager.getPMs()) {
-					vm = pm.getVirtualMachines().get((pm.getVirtualMachines().keySet().toArray(new Integer[0]))[0]);
+					// TODO: choose VM with good Utilization to get even better utilization
+					vm = pm.getVirtualMachines().get(
+							(pm.getVirtualMachines().keySet().toArray(new Integer[0]))[0]);
 					try {
-						vm.resizeVM(vm.getSize() + evt.getApp().getSize(), vm.getRAM() + evt.getApp().getRam(), vm.getCPU()
-								+ evt.getApp().getCpu());
+						vm.resizeVM(vm.getSize() + evt.getApp().getSize(), vm.getRAM()
+								+ evt.getApp().getRam(), vm.getCPU() + evt.getApp().getCpu());
 						break;
 					} catch (VMResizeException ex) {
 						vm = null;
@@ -190,7 +181,8 @@ public class SchedulerB extends AbstractScheduler {
 				}
 				if (vm == null) {
 					try {
-						vm = manager.startPhysicalMachine().startVirtualMachine(evt.getApp().getSize(), evt.getApp().getRam(),
+						vm = manager.startPhysicalMachine().startVirtualMachine(
+								evt.getApp().getSize(), evt.getApp().getRam(),
 								evt.getApp().getCpu(), vmType);
 					} catch (OutOfPMsException e) {
 						if (federation.askToOutsource(evt.getApp())) {
-- 
2.43.0