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