]> git.somenet.org - pub/jan/lsdc.git/blob - src/at/ac/tuwien/lsdc/sched/AbstractScheduler.java
small improvement
[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                 if(delayedApps.size() > 0)
234                         handleDelayedApps();
235                 
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));
242                 
243                 numTotalStarted += numStarted;
244                 numTotalStopped += numStopped;
245         }
246
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);
252                         totalDelayedApps ++;
253                 }
254
255                 delayedApps.clear();
256                 handleStartEvents(delayedStartEvents);
257         }
258
259         protected abstract void handleEndEvents(LinkedList<SchedulerEvent> events);
260
261         protected abstract void handleStartEvents(LinkedList<SchedulerEvent> events);
262
263         /**
264          * handle running of outsourced apps.
265          *
266          * @param events list of all events that happened in this timeslot.
267          */
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());
272                                 numCurrOutSourced++;
273                                 numTotalOutSourced++;
274                         }
275                 }
276         }
277
278         /**
279          * handle running of outsourced apps.
280          *
281          * @param events list of all events that happened in this timeslot.
282          */
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());
287                                 numCurrInSourced++;
288                                 numTotalInSourced++;
289                         }
290                 }
291         }
292
293         /**
294          * handle stopping of outsourced apps.
295          *
296          * @param events list of all events that happened in this timeslot.
297          */
298         protected void handleOutsourcedEndEvents(LinkedList<SchedulerEvent> events) {
299                 for (SchedulerEvent evt : events) {
300                         if (evt.getType() == EventType.endOutsourcedApplication) {
301                                 numCurrOutSourced--;
302                         }
303                 }
304         }
305
306         /**
307          * handle stopping of outsourced apps.
308          *
309          * @param events list of all events that happened in this timeslot.
310          */
311         protected void handleInsourcedEndEvents(LinkedList<SchedulerEvent> events) {
312                 for (SchedulerEvent evt : events) {
313                         if (evt.getType() == EventType.endInsourcedApplication) {
314                                 numCurrInSourced--;
315                         }
316                 }
317         }
318
319         /**
320          * Does the logging for each timestamp. It uses the CSVLogger to write directly to the specific
321          * scheduler/scenario csv file
322          */
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();
330                 try {
331                         logger.logSchedulerData(data);
332                 } catch (IOException e) {
333                         log.error("error logging data");
334                 }
335         }
336
337         /**
338          * this creates the total summary which should be written to a CSV at the end
339          *
340          * @return a ScenarioData Object that holds the values to be logged
341          */
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);
347         }
348
349         protected abstract String getSchedulerType();
350
351         public static long getCurrentTime() {
352                 return currTime;
353         }
354
355 }