1 package at.ac.tuwien.lsdc.sched;
4 import java.io.IOException;
5 import java.util.ArrayList;
6 import java.util.HashMap;
7 import java.util.LinkedList;
8 import java.util.SortedMap;
9 import java.util.TreeMap;
11 import org.slf4j.Logger;
12 import org.slf4j.LoggerFactory;
14 import at.ac.tuwien.lsdc.federation.Federation;
15 import at.ac.tuwien.lsdc.management.MachineManager;
16 import at.ac.tuwien.lsdc.types.Application;
17 import at.ac.tuwien.lsdc.types.ScenarioData;
18 import at.ac.tuwien.lsdc.types.ScenarioType;
19 import at.ac.tuwien.lsdc.types.SchedulerData;
20 import at.ac.tuwien.lsdc.types.SchedulerEvent;
21 import at.ac.tuwien.lsdc.types.SchedulerEvent.EventType;
22 import at.ac.tuwien.lsdc.types.VirtualMachine.VMType;
23 import at.ac.tuwien.lsdc.util.CSVLogger;
24 import at.ac.tuwien.lsdc.util.NumberUtils;
27 * Class doing all the generic scheduling work.
29 public abstract class AbstractScheduler {
31 private static final Logger log = LoggerFactory.getLogger(AbstractScheduler.class);
33 // the following types are only needed for correct
35 protected ScenarioType scenario;
36 protected int numTotalInSourced;
37 protected int numTotalOutSourced;
38 protected int numCurrInSourced;
39 protected int numCurrOutSourced;
40 protected int numStarted;
41 protected int numStopped;
42 protected int numTotalStarted;
43 protected int numTotalStopped;
44 protected double totalConsumption;
46 protected MachineManager manager;
47 protected File schedulerLog;
48 protected CSVLogger logger;
49 protected VMType vmType;
51 // List of Apps that were delayed due to not enough free resources.
52 protected ArrayList<Application> delayedApps;
54 private int totalDelayedApps;
56 * this map saves the following Type of Events: start of an Application, end of an
57 * Application(start outSourced, end outSourced, start inSourced, end inSourced)
59 protected SortedMap<Long, HashMap<EventType, LinkedList<SchedulerEvent>>> eventMap;
62 * Scheduler has an internal Time "Abstraction" at every point in time it checks for Events in
63 * his "EventList" and handles them (via the individual scheduling algorithm)
65 protected static long currTime = 0;
68 * the timestamp at which the Scheduler is finished it is updated with every added "EndEvent"
70 protected long endTime;
73 * All our cloud partners.
75 protected Federation federation;
77 public AbstractScheduler(int numPMs, int numCloudPartners, File schedulerLog,
78 ScenarioType scenario) throws IOException {
79 manager = new MachineManager(numPMs);
80 this.schedulerLog = schedulerLog;
81 this.scenario = scenario;
82 eventMap = new TreeMap<Long, HashMap<EventType, LinkedList<SchedulerEvent>>>();
83 logger = new CSVLogger(schedulerLog);
84 federation = new Federation(numCloudPartners);
85 delayedApps = new ArrayList<Application>();
89 * Initialize Scheduler with Data from CSV CSV will be parsed and sent as List<Application> to
92 public ScenarioData initAndStart(LinkedList<Application> apps) {
93 for (Application app : apps) {
94 insertStartEvent(app.getTimestamp(), app);
97 endTime = apps.getLast().getTimestamp() + 1;
100 return doEndLogging();
104 * Insert a start event into the map, at timestamp when the application should start
106 * @param timestamp the timestamp when the application should start
107 * @param app the application to start
109 protected void insertStartEvent(long timestamp, Application app) {
110 SchedulerEvent evt = new SchedulerEvent(timestamp, EventType.startApplication, app);
115 * Insert a start outsourced event into the map, at timestamp when the application should start
117 * @param timestamp the timestamp when the application should start
118 * @param app the application to start
120 protected void insertOutsourcedStartEvent(long timestamp, Application app) {
121 SchedulerEvent evt = new SchedulerEvent(timestamp, EventType.startOutsourcedApplication,
127 * Insert a start insourced event into the map, at timestamp when the application should start
129 * @param timestamp the timestamp when the application should start
130 * @param app the application to start
132 protected void insertInsourcedStartEvent(long timestamp, Application app) {
133 SchedulerEvent evt = new SchedulerEvent(timestamp, EventType.startInsourcedApplication,
139 * Insert a stop event into the map, at timestamp when the application should stop.
141 * @param timestamp the timestamp when the application should stop
142 * @param app the application to stop
144 protected void insertStopEvent(long timestamp, Application app) {
145 SchedulerEvent evt = new SchedulerEvent(timestamp, EventType.endApplication, app);
147 if (endTime < timestamp) {
153 * Insert a stop event into the map, at timestamp when the application should stop.
155 * @param timestamp the timestamp when the application should stop
156 * @param app the application to stop
158 protected void insertOutsourcedStopEvent(long timestamp, Application app) {
159 SchedulerEvent evt = new SchedulerEvent(timestamp, EventType.endOutsourcedApplication, app);
161 if (endTime < timestamp) {
167 * Insert a stop event into the map, at timestamp when the application should stop.
169 * @param timestamp the timestamp when the application should stop
170 * @param app the application to stop
172 protected void insertInsourcedStopEvent(long timestamp, Application app) {
173 SchedulerEvent evt = new SchedulerEvent(timestamp, EventType.endInsourcedApplication, app);
175 if (endTime < timestamp) {
180 private void insertEvent(SchedulerEvent evt) {
181 LinkedList<SchedulerEvent> list;
182 if (!eventMap.containsKey(evt.getTimestamp())) {
183 HashMap<EventType, LinkedList<SchedulerEvent>> map = new HashMap<EventType, LinkedList<SchedulerEvent>>();
184 eventMap.put(evt.getTimestamp(), map);
186 if (!eventMap.get(evt.getTimestamp()).containsKey(evt.getType())) {
187 list = new LinkedList<SchedulerEvent>();
188 eventMap.get(evt.getTimestamp()).put(evt.getType(), list);
190 list = eventMap.get(evt.getTimestamp()).get(evt.getType());
196 * Start the actual scheduling algorithm. Each scheduler will implement the method handleEvents
199 protected void startScheduling() {
201 if (eventMap.containsKey(currTime)) {
202 // log.info(events.size() + " events at timestamp " + currTime);
203 handleEvents(eventMap.get(currTime));
206 // advance Time to next step
209 if (currTime > endTime && delayedApps.size() == 0) {
210 // reached last Event, Scheduler will shut down
211 log.info("Last event reached at time " + currTime);
218 * this method is where the Scheduling Algorithm resides it reads the Events (start & stop of
221 * @param events the events to be read and used by the scheduler
223 protected void handleEvents(HashMap<EventType, LinkedList<SchedulerEvent>> events) {
227 if (events.containsKey(EventType.endApplication))
228 handleEndEvents(events.get(EventType.endApplication));
229 if (events.containsKey(EventType.endOutsourcedApplication))
230 handleOutsourcedEndEvents(events.get(EventType.endOutsourcedApplication));
231 if (events.containsKey(EventType.endInsourcedApplication))
232 handleInsourcedEndEvents(events.get(EventType.endInsourcedApplication));
233 if(delayedApps.size() > 0)
236 if (events.containsKey(EventType.startOutsourcedApplication))
237 handleOutsourcedStartEvents(events.get(EventType.startOutsourcedApplication));
238 if (events.containsKey(EventType.startApplication))
239 handleStartEvents(events.get(EventType.startApplication));
240 if (events.containsKey(EventType.startInsourcedApplication))
241 handleInsourcedStartEvents(events.get(EventType.startInsourcedApplication));
243 numTotalStarted += numStarted;
244 numTotalStopped += numStopped;
247 protected void handleDelayedApps() {
248 LinkedList<SchedulerEvent> delayedStartEvents = new LinkedList<SchedulerEvent>();
249 for (Application app : delayedApps) {
250 SchedulerEvent evt = new SchedulerEvent(currTime, EventType.startApplication, app);
251 delayedStartEvents.add(evt);
256 handleStartEvents(delayedStartEvents);
259 protected abstract void handleEndEvents(LinkedList<SchedulerEvent> events);
261 protected abstract void handleStartEvents(LinkedList<SchedulerEvent> events);
264 * handle running of outsourced apps.
266 * @param events list of all events that happened in this timeslot.
268 protected void handleOutsourcedStartEvents(LinkedList<SchedulerEvent> events) {
269 for (SchedulerEvent evt : events) {
270 if (evt.getType() == EventType.startOutsourcedApplication) {
271 insertOutsourcedStopEvent(currTime + evt.getApp().getDuration(), evt.getApp());
273 numTotalOutSourced++;
279 * handle running of outsourced apps.
281 * @param events list of all events that happened in this timeslot.
283 protected void handleInsourcedStartEvents(LinkedList<SchedulerEvent> events) {
284 for (SchedulerEvent evt : events) {
285 if (evt.getType() == EventType.startInsourcedApplication) {
286 insertInsourcedStopEvent(currTime + evt.getApp().getDuration(), evt.getApp());
294 * handle stopping of outsourced apps.
296 * @param events list of all events that happened in this timeslot.
298 protected void handleOutsourcedEndEvents(LinkedList<SchedulerEvent> events) {
299 for (SchedulerEvent evt : events) {
300 if (evt.getType() == EventType.endOutsourcedApplication) {
307 * handle stopping of outsourced apps.
309 * @param events list of all events that happened in this timeslot.
311 protected void handleInsourcedEndEvents(LinkedList<SchedulerEvent> events) {
312 for (SchedulerEvent evt : events) {
313 if (evt.getType() == EventType.endInsourcedApplication) {
320 * Does the logging for each timestamp. It uses the CSVLogger to write directly to the specific
321 * scheduler/scenario csv file
323 protected void doStateLogging() {
324 SchedulerData data = new SchedulerData(currTime, manager.getTotalRam(),
325 manager.getTotalCpu(), manager.getTotalSize(), manager.countCurrentlyRunningPMs(),
326 manager.countCurrentlyRunningVMs(), manager.getCurrentConsumption(),
327 numCurrInSourced, numCurrOutSourced, MachineManager.getTotalResizeCalls(), delayedApps.size(),
328 numStarted, numStopped);
329 totalConsumption += manager.getCurrentConsumption();
331 logger.logSchedulerData(data);
332 } catch (IOException e) {
333 log.error("error logging data");
338 * this creates the total summary which should be written to a CSV at the end
340 * @return a ScenarioData Object that holds the values to be logged
342 protected ScenarioData doEndLogging() {
343 return new ScenarioData(getSchedulerType(), scenario.toString(), manager.getTotalPMs(),
344 manager.getTotalVMs(), endTime, NumberUtils.roundDouble(totalConsumption),
345 numTotalInSourced, numTotalOutSourced, MachineManager.getTotalResizeCalls(), totalDelayedApps,
346 numTotalStarted, numTotalStopped);
349 protected abstract String getSchedulerType();
351 public static long getCurrentTime() {