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