]> git.somenet.org - pub/jan/lsdc.git/blob - src/at/ac/tuwien/lsdc/sched/AbstractScheduler.java
Applications now store their own nextID.
[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 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 stop event into the map, at timestamp when the application should stop.
123          *
124          * @param timestamp the timestamp when the application should stop
125          * @param app the application to stop
126          */
127         protected void insertStopEvent(long timestamp, Application app) {
128                 SchedulerEvent evt = new SchedulerEvent(timestamp, EventType.endApplication, app);
129                 insertEvent(evt);
130                 if (endTime < timestamp) {
131                         endTime = timestamp;
132                 }
133         }
134
135         /**
136          * Insert a stop event into the map, at timestamp when the application should stop.
137          *
138          * @param timestamp the timestamp when the application should stop
139          * @param app the application to stop
140          */
141         protected void insertOutsourcedStopEvent(long timestamp, Application app) {
142                 SchedulerEvent evt = new SchedulerEvent(timestamp, EventType.endOutsourcedApplication, app);
143                 insertEvent(evt);
144                 if (endTime < timestamp) {
145                         endTime = timestamp;
146                 }
147         }
148
149         private void insertEvent(SchedulerEvent evt) {
150                 LinkedList<SchedulerEvent> list;
151                 if (!eventMap.containsKey(evt.getTimestamp())) {
152                         HashMap<EventType, LinkedList<SchedulerEvent>> map = new HashMap<EventType, LinkedList<SchedulerEvent>>();
153                         eventMap.put(evt.getTimestamp(), map);
154                 }
155                 if (!eventMap.get(evt.getTimestamp()).containsKey(evt.getType())) {
156                         list = new LinkedList<SchedulerEvent>();
157                         eventMap.get(evt.getTimestamp()).put(evt.getType(), list);
158                 } else {
159                         list = eventMap.get(evt.getTimestamp()).get(evt.getType());
160                 }
161                 list.add(evt);
162         }
163
164         /**
165          * Start the actual scheduling algorithm. Each scheduler will implement the method handleEvents
166          * differently
167          */
168         protected void startScheduling() {
169                 while (true) {
170                         if (eventMap.containsKey(currTime)) {
171                                 // log.info(events.size() + " events at timestamp " + currTime);
172                                 handleEvents(eventMap.get(currTime));
173                         }
174                         doStateLogging();
175                         // advance Time to next step
176                         currTime++;
177
178                         if (currTime > endTime) {
179                                 // reached last Event, Scheduler will shut down
180                                 log.info("Last event reached at time " + currTime);
181                                 break;
182                         }
183                 }
184         }
185
186         /**
187          * this method is where the Scheduling Algorithm resides it reads the Events (start & stop of
188          * applications)
189          *
190          * @param events the events to be read and used by the scheduler
191          */
192         protected void handleEvents(HashMap<EventType, LinkedList<SchedulerEvent>> events) {
193                 if (events.containsKey(EventType.endApplication))
194                         handleEndEvents(events.get(EventType.endApplication));
195                 if (events.containsKey(EventType.endOutsourcedApplication))
196                         handleOutsourcedEndEvents(events.get(EventType.endOutsourcedApplication));
197                 handleDelayedApps();
198                 if (events.containsKey(EventType.startOutsourcedApplication))
199                         handleOutsourcedStartEvents(events.get(EventType.startOutsourcedApplication));
200                 if (events.containsKey(EventType.startApplication))
201                         handleStartEvents(events.get(EventType.startApplication));
202         }
203
204         protected void handleDelayedApps() {
205                 LinkedList<SchedulerEvent> delayedStartEvents = new LinkedList<SchedulerEvent>();
206                 for (Application app : delayedApps) {
207                         SchedulerEvent evt = new SchedulerEvent(currTime, EventType.startApplication, app);
208                         delayedStartEvents.add(evt);
209                 }
210                 delayedApps.clear();
211                 handleStartEvents(delayedStartEvents);
212         }
213
214         protected abstract void handleEndEvents(LinkedList<SchedulerEvent> events);
215
216         protected abstract void handleStartEvents(LinkedList<SchedulerEvent> events);
217
218         /**
219          * handle running of outsourced apps.
220          *
221          * @param events list of all events that happened in this timeslot.
222          */
223         protected void handleOutsourcedStartEvents(LinkedList<SchedulerEvent> events) {
224                 for (SchedulerEvent evt : events) {
225                         if (evt.getType() == EventType.startOutsourcedApplication) {
226                                 insertOutsourcedStopEvent(currTime + evt.getApp().getDuration(), evt.getApp());
227                                 numCurrOutSourced++;
228                                 numTotalOutSourced++;
229                         }
230                 }
231         }
232
233         /**
234          * handle stopping of outsourced apps.
235          *
236          * @param events list of all events that happened in this timeslot.
237          */
238         protected void handleOutsourcedEndEvents(LinkedList<SchedulerEvent> events) {
239                 for (SchedulerEvent evt : events) {
240                         if (evt.getType() == EventType.endOutsourcedApplication) {
241                                 numCurrOutSourced--;
242                         }
243                 }
244         }
245
246         /**
247          * Does the logging for each timestamp. It uses the CSVLogger to write directly to the specific
248          * scheduler/scenario csv file
249          */
250         protected void doStateLogging() {
251                 SchedulerData data = new SchedulerData(currTime, manager.getTotalRam(),
252                                 manager.getTotalCpu(), manager.getTotalSize(), manager.countCurrentlyRunningPMs(),
253                                 manager.countCurrentlyRunningVMs(), manager.getCurrentConsumption(),
254                                 numCurrInSourced, numCurrOutSourced);
255                 totalConsumption += manager.getCurrentConsumption();
256                 try {
257                         logger.logSchedulerData(data);
258                 } catch (IOException e) {
259                         log.error("error logging data");
260                 }
261         }
262
263         /**
264          * this creates the total summary which should be written to a CSV at the end
265          *
266          * @return a ScenarioData Object that holds the values to be logged
267          */
268         protected ScenarioData doEndLogging() {
269                 return new ScenarioData(getSchedulerType(), scenario.toString(), manager.getTotalPMs(),
270                                 manager.getTotalVMs(), endTime, NumberUtils.roundDouble(totalConsumption),
271                                 numTotalInSourced, numTotalOutSourced);
272         }
273
274         protected abstract String getSchedulerType();
275
276 }