]> git.somenet.org - pub/jan/lsdc.git/blob - src/at/ac/tuwien/lsdc/sched/AbstractScheduler.java
fix stop Events in SchedB, count start & stop in SchedC
[pub/jan/lsdc.git] / src / at / ac / tuwien / lsdc / sched / AbstractScheduler.java
1 package at.ac.tuwien.lsdc.sched;
2
3 import java.io.File;
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;
10
11 import org.slf4j.Logger;
12 import org.slf4j.LoggerFactory;
13
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;
25
26 /**
27  * Class doing all the generic scheduling work.
28  */
29 public abstract class AbstractScheduler {
30
31         private static final Logger log = LoggerFactory.getLogger(AbstractScheduler.class);
32
33         // the following types are only needed for correct
34         // log output
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;
45
46         protected MachineManager manager;
47         protected File schedulerLog;
48         protected CSVLogger logger;
49         protected VMType vmType;
50
51         // List of Apps that were delayed due to not enough free resources.
52         protected ArrayList<Application> delayedApps;
53
54         private int totalDelayedApps;
55         /**
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)
58          */
59         protected SortedMap<Long, HashMap<EventType, LinkedList<SchedulerEvent>>> eventMap;
60
61         /**
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)
64          */
65         protected static long currTime = 0;
66
67         /**
68          * the timestamp at which the Scheduler is finished it is updated with every added "EndEvent"
69          */
70         protected long endTime;
71
72         /**
73          * All our cloud partners.
74          */
75         protected Federation federation;
76
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>();
86         }
87
88         /**
89          * Initialize Scheduler with Data from CSV CSV will be parsed and sent as List<Application> to
90          * Scheduler
91          */
92         public ScenarioData initAndStart(LinkedList<Application> apps) {
93                 for (Application app : apps) {
94                         insertStartEvent(app.getTimestamp(), app);
95                 }
96
97                 endTime = apps.getLast().getTimestamp() + 1;
98
99                 startScheduling();
100                 return doEndLogging();
101         }
102
103         /**
104          * Insert a start event into the map, at timestamp when the application should start
105          *
106          * @param timestamp the timestamp when the application should start
107          * @param app the application to start
108          */
109         protected void insertStartEvent(long timestamp, Application app) {
110                 SchedulerEvent evt = new SchedulerEvent(timestamp, EventType.startApplication, app);
111                 insertEvent(evt);
112         }
113
114         /**
115          * Insert a start outsourced event into the map, at timestamp when the application should start
116          *
117          * @param timestamp the timestamp when the application should start
118          * @param app the application to start
119          */
120         protected void insertOutsourcedStartEvent(long timestamp, Application app) {
121                 SchedulerEvent evt = new SchedulerEvent(timestamp, EventType.startOutsourcedApplication,
122                                 app);
123                 insertEvent(evt);
124         }
125
126         /**
127          * Insert a start insourced event into the map, at timestamp when the application should start
128          *
129          * @param timestamp the timestamp when the application should start
130          * @param app the application to start
131          */
132         protected void insertInsourcedStartEvent(long timestamp, Application app) {
133                 SchedulerEvent evt = new SchedulerEvent(timestamp, EventType.startInsourcedApplication,
134                                 app);
135                 insertEvent(evt);
136         }
137
138         /**
139          * Insert a stop event into the map, at timestamp when the application should stop.
140          *
141          * @param timestamp the timestamp when the application should stop
142          * @param app the application to stop
143          */
144         protected void insertStopEvent(long timestamp, Application app) {
145                 SchedulerEvent evt = new SchedulerEvent(timestamp, EventType.endApplication, app);
146                 insertEvent(evt);
147                 if (endTime < timestamp) {
148                         endTime = timestamp;
149                 }
150         }
151
152         /**
153          * Insert a stop event into the map, at timestamp when the application should stop.
154          *
155          * @param timestamp the timestamp when the application should stop
156          * @param app the application to stop
157          */
158         protected void insertOutsourcedStopEvent(long timestamp, Application app) {
159                 SchedulerEvent evt = new SchedulerEvent(timestamp, EventType.endOutsourcedApplication, app);
160                 insertEvent(evt);
161                 if (endTime < timestamp) {
162                         endTime = timestamp;
163                 }
164         }
165
166         /**
167          * Insert a stop event into the map, at timestamp when the application should stop.
168          *
169          * @param timestamp the timestamp when the application should stop
170          * @param app the application to stop
171          */
172         protected void insertInsourcedStopEvent(long timestamp, Application app) {
173                 SchedulerEvent evt = new SchedulerEvent(timestamp, EventType.endInsourcedApplication, app);
174                 insertEvent(evt);
175                 if (endTime < timestamp) {
176                         endTime = timestamp;
177                 }
178         }
179
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);
185                 }
186                 if (!eventMap.get(evt.getTimestamp()).containsKey(evt.getType())) {
187                         list = new LinkedList<SchedulerEvent>();
188                         eventMap.get(evt.getTimestamp()).put(evt.getType(), list);
189                 } else {
190                         list = eventMap.get(evt.getTimestamp()).get(evt.getType());
191                 }
192                 list.add(evt);
193         }
194
195         /**
196          * Start the actual scheduling algorithm. Each scheduler will implement the method handleEvents
197          * differently
198          */
199         protected void startScheduling() {
200                 while (true) {
201                         if (eventMap.containsKey(currTime)) {
202                                 // log.info(events.size() + " events at timestamp " + currTime);
203                                 handleEvents(eventMap.get(currTime));
204                         }
205                         doStateLogging();
206                         // advance Time to next step
207                         currTime++;
208
209                         if (currTime > endTime  &&  delayedApps.size() == 0) {
210                                 // reached last Event, Scheduler will shut down
211                                 log.info("Last event reached at time " + currTime);
212                                 break;
213                         }
214                 }
215         }
216
217         /**
218          * this method is where the Scheduling Algorithm resides it reads the Events (start & stop of
219          * applications)
220          *
221          * @param events the events to be read and used by the scheduler
222          */
223         protected void handleEvents(HashMap<EventType, LinkedList<SchedulerEvent>> events) {
224                 numStarted = 0;
225                 numStopped = 0;
226                 
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                 handleDelayedApps();
234                 if (events.containsKey(EventType.startOutsourcedApplication))
235                         handleOutsourcedStartEvents(events.get(EventType.startOutsourcedApplication));
236                 if (events.containsKey(EventType.startApplication))
237                         handleStartEvents(events.get(EventType.startApplication));
238                 if (events.containsKey(EventType.startInsourcedApplication))
239                         handleInsourcedStartEvents(events.get(EventType.startInsourcedApplication));
240                 
241                 numTotalStarted += numStarted;
242                 numTotalStopped += numStopped;
243         }
244
245         protected void handleDelayedApps() {
246                 LinkedList<SchedulerEvent> delayedStartEvents = new LinkedList<SchedulerEvent>();
247                 for (Application app : delayedApps) {
248                         SchedulerEvent evt = new SchedulerEvent(currTime, EventType.startApplication, app);
249                         delayedStartEvents.add(evt);
250                         totalDelayedApps ++;
251                 }
252                 delayedApps.clear();
253                 handleStartEvents(delayedStartEvents);
254         }
255
256         protected abstract void handleEndEvents(LinkedList<SchedulerEvent> events);
257
258         protected abstract void handleStartEvents(LinkedList<SchedulerEvent> events);
259
260         /**
261          * handle running of outsourced apps.
262          *
263          * @param events list of all events that happened in this timeslot.
264          */
265         protected void handleOutsourcedStartEvents(LinkedList<SchedulerEvent> events) {
266                 for (SchedulerEvent evt : events) {
267                         if (evt.getType() == EventType.startOutsourcedApplication) {
268                                 insertOutsourcedStopEvent(currTime + evt.getApp().getDuration(), evt.getApp());
269                                 numCurrOutSourced++;
270                                 numTotalOutSourced++;
271                         }
272                 }
273         }
274
275         /**
276          * handle running of outsourced apps.
277          *
278          * @param events list of all events that happened in this timeslot.
279          */
280         protected void handleInsourcedStartEvents(LinkedList<SchedulerEvent> events) {
281                 for (SchedulerEvent evt : events) {
282                         if (evt.getType() == EventType.startInsourcedApplication) {
283                                 insertInsourcedStopEvent(currTime + evt.getApp().getDuration(), evt.getApp());
284                                 numCurrInSourced++;
285                                 numTotalInSourced++;
286                         }
287                 }
288         }
289
290         /**
291          * handle stopping of outsourced apps.
292          *
293          * @param events list of all events that happened in this timeslot.
294          */
295         protected void handleOutsourcedEndEvents(LinkedList<SchedulerEvent> events) {
296                 for (SchedulerEvent evt : events) {
297                         if (evt.getType() == EventType.endOutsourcedApplication) {
298                                 numCurrOutSourced--;
299                         }
300                 }
301         }
302
303         /**
304          * handle stopping of outsourced apps.
305          *
306          * @param events list of all events that happened in this timeslot.
307          */
308         protected void handleInsourcedEndEvents(LinkedList<SchedulerEvent> events) {
309                 for (SchedulerEvent evt : events) {
310                         if (evt.getType() == EventType.endInsourcedApplication) {
311                                 numCurrInSourced--;
312                         }
313                 }
314         }
315
316         /**
317          * Does the logging for each timestamp. It uses the CSVLogger to write directly to the specific
318          * scheduler/scenario csv file
319          */
320         protected void doStateLogging() {
321                 SchedulerData data = new SchedulerData(currTime, manager.getTotalRam(),
322                                 manager.getTotalCpu(), manager.getTotalSize(), manager.countCurrentlyRunningPMs(),
323                                 manager.countCurrentlyRunningVMs(), manager.getCurrentConsumption(),
324                                 numCurrInSourced, numCurrOutSourced, MachineManager.getTotalResizeCalls(), delayedApps.size(), 
325                                 numStarted, numStopped);
326                 totalConsumption += manager.getCurrentConsumption();
327                 try {
328                         logger.logSchedulerData(data);
329                 } catch (IOException e) {
330                         log.error("error logging data");
331                 }
332         }
333
334         /**
335          * this creates the total summary which should be written to a CSV at the end
336          *
337          * @return a ScenarioData Object that holds the values to be logged
338          */
339         protected ScenarioData doEndLogging() {
340                 return new ScenarioData(getSchedulerType(), scenario.toString(), manager.getTotalPMs(),
341                                 manager.getTotalVMs(), endTime, NumberUtils.roundDouble(totalConsumption),
342                                 numTotalInSourced, numTotalOutSourced, MachineManager.getTotalResizeCalls(), totalDelayedApps, 
343                                 numTotalStarted, numTotalStopped);
344         }
345
346         protected abstract String getSchedulerType();
347
348         public static long getCurrentTime() {
349                 return currTime;
350         }
351
352 }