]> git.somenet.org - pub/jan/lsdc.git/blob - src/at/ac/tuwien/lsdc/sched/SchedulerB.java
SchedB now has Federation and Delaying of apps.
[pub/jan/lsdc.git] / src / at / ac / tuwien / lsdc / sched / SchedulerB.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.LinkedList;
7
8 import org.slf4j.Logger;
9 import org.slf4j.LoggerFactory;
10
11 import at.ac.tuwien.lsdc.exception.OutOfPMsException;
12 import at.ac.tuwien.lsdc.exception.VMResizeException;
13 import at.ac.tuwien.lsdc.types.Application;
14 import at.ac.tuwien.lsdc.types.PhysicalMachine;
15 import at.ac.tuwien.lsdc.types.ScenarioType;
16 import at.ac.tuwien.lsdc.types.SchedulerEvent;
17 import at.ac.tuwien.lsdc.types.SchedulerEvent.EventType;
18 import at.ac.tuwien.lsdc.types.SchedulerType;
19 import at.ac.tuwien.lsdc.types.VirtualMachine;
20 import at.ac.tuwien.lsdc.types.VirtualMachine.VMType;
21
22 /**
23  * Scheduler B.
24  * 
25  * Initial State: All PMs switched off. If an application arrives, try to modify
26  * size, CPU and RAM of an existing VM to run the application. If no VM is
27  * running, create a new one (start a new PM if necessary). If the application
28  * has finished decrease the size, CPU and RAM of the VM. If no applications are
29  * running on a VM, shut down the VM. If no VM is running on a PM, shut down the
30  * PM. Try to get a maximum of utilization on every PM. Migration: Try to move
31  * applications from VMs to other VMs to get a better utilization and to use
32  * less PMs.
33  * 
34  * @author jan
35  * 
36  */
37 public class SchedulerB extends AbstractScheduler {
38         /**
39          * Logger.
40          */
41         private static final Logger LOG = LoggerFactory.getLogger(SchedulerB.class);
42
43         /**
44          * List of Apps that were delayed due to not enough free resources. TODO: move
45          * to abstractSched?
46          */
47         private ArrayList<Application> delayedApps;
48
49         public SchedulerB(int numPMs, int numCloudPartners, File schedulerLog, ScenarioType scenario) throws IOException {
50                 super(numPMs, numCloudPartners, schedulerLog, scenario);
51
52                 vmType = VMType.Resizable;
53                 delayedApps = new ArrayList<Application>();
54         }
55
56         @Override
57         protected void handleEvents(LinkedList<SchedulerEvent> events) {
58                 LOG.debug("handleEvents():" + events);
59                 handleEndEvents(events);
60                 handleOutsourcedEndEvents(events);
61                 runMigration();
62                 runDelayedApps();
63                 handleOutsourcedStartEvents(events);
64                 handleStartEvents(events);
65         }
66
67         /**
68          * handle running of outsourced apps.
69          * 
70          * @param events
71          *          list of all events that happened in this timeslot.
72          */
73         private void handleOutsourcedStartEvents(LinkedList<SchedulerEvent> events) {
74                 for (SchedulerEvent evt : events) {
75                         if (evt.getType() == EventType.startOutsourcedApplication) {
76                                 insertOutsourcedStopEvent(currTime + evt.getApp().getDuration(), evt.getApp());
77                                 numCurrOutSourced++;
78                                 numTotalOutSourced++;
79                         }
80                 }
81         }
82
83         /**
84          * handle stopping of outsourced apps.
85          * 
86          * @param events
87          *          list of all events that happened in this timeslot.
88          */
89         private void handleOutsourcedEndEvents(LinkedList<SchedulerEvent> events) {
90                 for (SchedulerEvent evt : events) {
91                         if (evt.getType() == EventType.endOutsourcedApplication) {
92                                 numCurrOutSourced--;
93                         }
94                 }
95         }
96
97         /**
98          * Check if we have any delayed apps. Try to launch them.
99          */
100         private void runDelayedApps() {
101                 ArrayList<Application> newDelayedApps = new ArrayList<Application>();
102                 for (int i = 0; i < delayedApps.size(); i++) {
103                         Application app = delayedApps.get(i);
104                         VirtualMachine vm = null;
105                         for (PhysicalMachine pm : manager.getPMs()) {
106                                 vm = pm.getVirtualMachines().get((pm.getVirtualMachines().keySet().toArray(new Integer[0]))[0]);
107                                 try {
108                                         vm.resizeVM(vm.getSize() + app.getSize(), vm.getRAM() + app.getRam(), vm.getCPU() + app.getCpu());
109                                         break;
110                                 } catch (VMResizeException ex) {
111                                         vm = null;
112                                 }
113                         }
114                         if (vm == null) {
115                                 try {
116                                         vm = manager.startPhysicalMachine().startVirtualMachine(app.getSize(), app.getRam(), app.getCpu(), vmType);
117                                 } catch (OutOfPMsException e) {
118                                         // LOG.error("failed to start PM.", e);
119                                         if (federation.askToOutsource(app)) {
120                                                 insertOutsourcedStartEvent(currTime + 1, app);
121                                         } else
122                                                 LOG.info("delaying the start of:" + app);
123                                         return;
124                                 }
125                         }
126                         vm.startApplication(app);
127                         app.setRunningOn(vm);
128                         insertStopEvent(currTime + app.getDuration(), app);
129                 }
130                 delayedApps = newDelayedApps;
131         }
132
133         /**
134          * Check if we can free up a VM to shut it down.
135          */
136         private void runMigration() {
137                 // TODO Auto-generated method stub
138         }
139
140         /**
141          * Cleanup completed apps. Downsize VMs and if an VM becomes empty, shut down
142          * VM + PM.
143          * 
144          * @param events
145          *          list of all events that happened in this timeslot.
146          */
147         protected void handleEndEvents(LinkedList<SchedulerEvent> events) {
148                 LOG.debug("stopApps():" + events);
149                 for (SchedulerEvent evt : events) {
150                         if (evt.getType() == EventType.endApplication) {
151                                 VirtualMachine vm = evt.getApp().getRunningOn();
152                                 evt.getApp().setRunningOn(null);
153                                 vm.stopApplication(evt.getApp());
154                                 try {
155                                         vm.resizeVM(vm.getSize() - evt.getApp().getSize(), vm.getRAM() - evt.getApp().getRam(), vm.getCPU()
156                                                         - evt.getApp().getCpu());
157                                 } catch (VMResizeException e) {
158                                         // LOG.error("failed to resize VM: " + e.getVm(), e);
159                                 }
160                                 if (vm.getApplications().size() == 0) {
161                                         PhysicalMachine pm = vm.getRunningOn();
162                                         pm.stopVirtualMachine(vm);
163                                         manager.stopPhysicalMachine(pm.getId());
164                                 }
165                         }
166                 }
167         }
168
169         /**
170          * Try to start all Apps. Upsize the VM, if not possible start another PM, if
171          * not possible, delay start.
172          * 
173          * @param events
174          *          list of all events that happened in this timeslot.
175          */
176         protected void handleStartEvents(LinkedList<SchedulerEvent> events) {
177                 LOG.debug("startApps():" + events);
178                 for (SchedulerEvent evt : events) {
179                         if (evt.getType() == EventType.startApplication) {
180                                 VirtualMachine vm = null;
181                                 for (PhysicalMachine pm : manager.getPMs()) {
182                                         vm = pm.getVirtualMachines().get((pm.getVirtualMachines().keySet().toArray(new Integer[0]))[0]);
183                                         try {
184                                                 vm.resizeVM(vm.getSize() + evt.getApp().getSize(), vm.getRAM() + evt.getApp().getRam(), vm.getCPU()
185                                                                 + evt.getApp().getCpu());
186                                                 break;
187                                         } catch (VMResizeException ex) {
188                                                 vm = null;
189                                         }
190                                 }
191                                 if (vm == null) {
192                                         try {
193                                                 vm = manager.startPhysicalMachine().startVirtualMachine(evt.getApp().getSize(), evt.getApp().getRam(),
194                                                                 evt.getApp().getCpu(), vmType);
195                                         } catch (OutOfPMsException e) {
196                                                 if (federation.askToOutsource(evt.getApp())) {
197                                                         insertOutsourcedStartEvent(currTime + 1, evt.getApp());
198                                                 } else
199                                                         LOG.info("delaying the start of:" + evt.getApp());
200                                                 delayedApps.add(evt.getApp());
201                                                 return;
202                                         }
203                                 }
204                                 vm.startApplication(evt.getApp());
205                                 evt.getApp().setRunningOn(vm);
206                                 insertStopEvent(currTime + evt.getApp().getDuration(), evt.getApp());
207                         }
208                 }
209         }
210
211         @Override
212         protected String getSchedulerType() {
213                 return SchedulerType.B.toString();
214         }
215
216 }