[haizea-commit] r599 - in branches/TP2.0/src/haizea/core: . scheduler

haizea-commit at mailman.cs.uchicago.edu haizea-commit at mailman.cs.uchicago.edu
Fri Jul 3 12:07:08 CDT 2009


Author: borja
Date: 2009-07-03 12:07:07 -0500 (Fri, 03 Jul 2009)
New Revision: 599

Modified:
   branches/TP2.0/src/haizea/core/leases.py
   branches/TP2.0/src/haizea/core/scheduler/lease_scheduler.py
   branches/TP2.0/src/haizea/core/scheduler/vm_scheduler.py
Log:
Schedule reevaluation (after a prematurely ending lease) is done (still needs a lot of testing). Got rid of horrible "slideback" algorithm used in TP1.x.

Modified: branches/TP2.0/src/haizea/core/leases.py
===================================================================
--- branches/TP2.0/src/haizea/core/leases.py	2009-07-03 14:18:57 UTC (rev 598)
+++ branches/TP2.0/src/haizea/core/leases.py	2009-07-03 17:07:07 UTC (rev 599)
@@ -414,6 +414,11 @@
                 exact.set("time", str(start))
                 
             lease = Lease.from_xml_element(lease)
+            
+            realduration = r.find("realduration")
+            if realduration != None:
+                lease.duration.known = Parser.DateTimeDeltaFromString(realduration.get("time"))
+
             self.entries.append(lease)
             
     

Modified: branches/TP2.0/src/haizea/core/scheduler/lease_scheduler.py
===================================================================
--- branches/TP2.0/src/haizea/core/scheduler/lease_scheduler.py	2009-07-03 14:18:57 UTC (rev 598)
+++ branches/TP2.0/src/haizea/core/scheduler/lease_scheduler.py	2009-07-03 17:07:07 UTC (rev 599)
@@ -178,13 +178,13 @@
         Arguments:
         nowtime -- Time at which to check for starting/ending reservations.
         """
-        
+
         # Find starting/ending reservations
         starting = self.slottable.get_reservations_starting_at(nowtime)
         starting = [res for res in starting if res.state == ResourceReservation.STATE_SCHEDULED]
         ending = self.slottable.get_reservations_ending_at(nowtime)
         ending = [res for res in ending if res.state == ResourceReservation.STATE_ACTIVE]
-        
+
         # Process ending reservations
         for rr in ending:
             lease = rr.lease
@@ -373,8 +373,18 @@
             nexttime = get_clock().get_next_schedulable_time()
             # We need to reevaluate the schedule to see if there are any future
             # reservations that we can slide back.
-            self.__reevaluate_schedule(lease, vmrr.nodes.values(), nexttime, [])
+            self.reevaluate_future_leases(vmrr.nodes.values(), nexttime)
 
+    def reevaluate_future_leases(self, nodes, nexttime):
+        res = list(self.vm_scheduler.future_reservations) # TODO: get through a function
+        for l in res:
+            vmrr = l.get_last_vmrr()
+            # TODO: Check if it's scheduled on any of the nodes that
+            #    got freed up
+            self.vm_scheduler.cancel_vm(vmrr)
+            l.remove_vmrr(vmrr)
+            # TODO: This earliest is sure to change to something else
+            self.__schedule_lease(l, nexttime)
 
     def is_queue_empty(self):
         """Return True is the queue is empty, False otherwise"""
@@ -404,7 +414,7 @@
         done = False
         newqueue = Queue(self)
         while not done and not self.is_queue_empty():
-            if not self.vm_scheduler.can_reserve_besteffort_in_future() and self.slottable.isFull(nexttime):
+            if not self.vm_scheduler.can_reserve_in_future() and self.slottable.isFull(nexttime):
                 self.logger.debug("Used up all future reservations and slot table is full. Skipping rest of queue.")
                 done = True
             else:
@@ -443,6 +453,10 @@
             # Figure out earliest start times based on
             # image schedule and reusable images
             earliest = self.preparation_scheduler.find_earliest_starting_times(lease, nexttime)
+        elif lease_state == Lease.STATE_READY or lease_state == Lease.STATE_SCHEDULED:
+            # This is a lease that is being rescheduled.
+            # TODO: The following is not really what has to be done
+            earliest = self.preparation_scheduler.find_earliest_starting_times(lease, nexttime)            
         elif lease_state == Lease.STATE_SUSPENDED_QUEUED:
             # No need to transfer images from repository
             # (only intra-node transfer)
@@ -555,50 +569,7 @@
             
         self.logger.vdebug("Lease after preemption:")
         lease.print_contents()
-        
-        
-    def __reevaluate_schedule(self, endinglease, nodes, nexttime, checkedleases):
-        """ Reevaluate the schedule after a lease ends prematurely
-        
-        After a lease ends prematurely, resources may become available. If so,
-        any lease that was scheduled under the assumption that the earliest starting time
-        was after the lease that ended prematurely, we will be able to start that
-        lease earlier than expected.
-        
-        TODO: Refine the backfilling algorithm, both here and in the VMScheduler.
-        Currently, only aggressive backfilling is supported, and somewhat crudely
-        (still better than no backfilling at all, though). In particular, it might
-        be a good idea to just do away with the "slideback" algorithm and simply
-        keep better track of what leases have been scheduled in the future, and 
-        just reschedule them (almost) as if they had been submitted again.
-        
-        Arguments:
-        endinglease -- The lease that ended prematurely and prompted a schedule reevaluation
-        nodes -- Physical nodes where schedule will be reevaluated
-        nexttime -- The next time at which the scheduler can allocate resources.
-        checkedleases -- What leases have been already checked for rescheduling (regardless
-                         of whether we were actually able to reschedule them). This method
-                         uses a recursive algorithm, so the value of this argument has to be
-                         initially [] (the empty list)
-        """        
-        
-        self.logger.debug("Reevaluating schedule. Checking for leases scheduled in nodes %s after %s" %(nodes, nexttime)) 
-        leases = []
-        vmrrs = self.slottable.get_next_reservations_in_nodes(nexttime, nodes, rr_type=VMResourceReservation, immediately_next=True)
-        leases = set([rr.lease for rr in vmrrs])
-        leases = [l for l in leases if isinstance(l, BestEffortLease) and l.get_state() in (Lease.STATE_SUSPENDED_SCHEDULED, Lease.STATE_READY) and not l in checkedleases]
-        for lease in leases:
-            self.logger.debug("Found lease %i" % lease.id)
-            lease.print_contents()
-            # Earliest time can't be earlier than time when images will be
-            # available in node
-            earliest = max(nexttime, lease.imagesavail)
-            self.vm_scheduler.slideback(lease, earliest)
-            checkedleases.append(lease)
-        #for l in leases:
-        #    vmrr, susprr = l.getLastVMRR()
-        #    self.reevaluateSchedule(l, vmrr.nodes.values(), vmrr.end, checkedleases)        
-        
+                
   
     def __enqueue(self, lease):
         """Queues a best-effort lease request

Modified: branches/TP2.0/src/haizea/core/scheduler/vm_scheduler.py
===================================================================
--- branches/TP2.0/src/haizea/core/scheduler/vm_scheduler.py	2009-07-03 14:18:57 UTC (rev 598)
+++ branches/TP2.0/src/haizea/core/scheduler/vm_scheduler.py	2009-07-03 17:07:07 UTC (rev 599)
@@ -77,7 +77,7 @@
         elif backfilling == constants.BACKFILLING_INTERMEDIATE:
             self.maxres = get_config().get("backfilling-reservations")
 
-        self.numbesteffortres = 0
+        self.future_reservations = set()
 
     def schedule(self, lease, nexttime, earliest):
         if lease.get_type() == Lease.BEST_EFFORT:
@@ -124,7 +124,7 @@
         shutdown_time = self.__estimate_shutdown_time(lease)
 
         if allow_reservation_in_future == None:
-            allow_reservation_in_future = self.can_reserve_besteffort_in_future()
+            allow_reservation_in_future = self.can_reserve_in_future()
 
         canmigrate = get_config().get("migration")
 
@@ -259,7 +259,7 @@
             self.__schedule_shutdown(vmrr)
         
         if reservation:
-            self.numbesteffortres += 1
+            self.future_reservations.add(lease)
 
         susp_str = res_str = ""
         if mustresume:
@@ -329,7 +329,7 @@
     def cancel_vm(self, vmrr):
 
         if vmrr.backfill_reservation == True:
-            self.numbesteffortres -= 1
+            self.future_reservations.remove(vmrr.lease)
 
         # If there are any pre-RRs that are scheduled, remove them
         for rr in vmrr.pre_rrs:
@@ -338,9 +338,9 @@
 
         # If there are any post RRs, remove them
         for rr in vmrr.post_rrs:
-            self.slottable.removeReservation(rr)
+            self.slottable.remove_reservation(rr)
         
-        self.slottable.removeReservation(vmrr)
+        self.slottable.remove_reservation(vmrr)
 
     
     def preempt_vm(self, vmrr, t):
@@ -351,67 +351,7 @@
         self.slottable.update_reservation_with_key_change(vmrr, old_start, old_end)
         for susprr in vmrr.post_rrs:
             self.slottable.add_reservation(susprr)
-        
-    def slideback(self, lease, earliest):
-        vmrr = lease.get_last_vmrr()
-        # Save original start and end time of the vmrr
-        old_start = vmrr.start
-        old_end = vmrr.end
-        nodes = vmrr.nodes.values()
-        if lease.get_state() == Lease.STATE_SUSPENDED_SCHEDULED:
-            originalstart = vmrr.pre_rrs[0].start
-        else:
-            originalstart = vmrr.start
-        cp = self.slottable.findChangePointsAfter(after=earliest, until=originalstart, nodes=nodes)
-        cp = [earliest] + cp
-        newstart = None
-        for p in cp:
-            self.slottable.availabilitywindow.initWindow(p, lease.requested_resources, canpreempt=False)
-            self.slottable.availabilitywindow.printContents()
-            if self.slottable.availabilitywindow.fitAtStart(nodes=nodes) >= lease.numnodes:
-                (end, canfit) = self.slottable.availabilitywindow.findPhysNodesForVMs(lease.numnodes, originalstart)
-                if end == originalstart and set(nodes) <= set(canfit.keys()):
-                    self.logger.debug("Can slide back to %s" % p)
-                    newstart = p
-                    break
-        if newstart == None:
-            # Can't slide back. Leave as is.
-            pass
-        else:
-            diff = originalstart - newstart
-            if lease.get_state() == Lease.STATE_SUSPENDED_SCHEDULED:
-                resmrrs = [r for r in vmrr.pre_rrs if isinstance(r, ResumptionResourceReservation)]
-                for resmrr in resmrrs:
-                    resmrr_old_start = resmrr.start
-                    resmrr_old_end = resmrr.end
-                    resmrr.start -= diff
-                    resmrr.end -= diff
-                    self.slottable.update_reservation_with_key_change(resmrr, resmrr_old_start, resmrr_old_end)
-            vmrr.update_start(vmrr.start - diff)
             
-            # If the lease was going to be suspended, check to see if
-            # we don't need to suspend any more.
-            remdur = lease.duration.get_remaining_duration()
-            if vmrr.is_suspending() and vmrr.end - newstart >= remdur: 
-                vmrr.update_end(vmrr.start + remdur)
-                for susprr in vmrr.post_rrs:
-                    self.slottable.removeReservation(susprr)
-                vmrr.post_rrs = []
-            else:
-                vmrr.update_end(vmrr.end - diff)
-                
-            if not vmrr.is_suspending():
-                # If the VM was set to shutdown, we need to slideback the shutdown RRs
-                for rr in vmrr.post_rrs:
-                    rr_old_start = rr.start
-                    rr_old_end = rr.end
-                    rr.start -= diff
-                    rr.end -= diff
-                    self.slottable.update_reservation_with_key_change(rr, rr_old_start, rr_old_end)
-
-            self.slottable.update_reservation_with_key_change(vmrr, old_start, old_end)
-            self.logger.vdebug("New lease descriptor (after slideback):")
-            lease.print_contents()        
         
     def get_utilization(self, time):
         total = self.slottable.get_total_capacity()
@@ -440,8 +380,8 @@
         return can_suspend
 
 
-    def can_reserve_besteffort_in_future(self):
-        return self.numbesteffortres < self.maxres
+    def can_reserve_in_future(self):
+        return len(self.future_reservations) < self.maxres
                 
     def is_backfilling(self):
         return self.maxres > 0
@@ -822,7 +762,7 @@
         rr.state = ResourceReservation.STATE_DONE
        
         if rr.backfill_reservation == True:
-            self.numbesteffortres -= 1
+            self.future_reservations.remove(l)
                 
         self.logger.vdebug("LEASE-%i After:" % l.id)
         l.print_contents()
@@ -832,7 +772,7 @@
     def _handle_unscheduled_end_vm(self, l, vmrr):
         self.logger.info("LEASE-%i The VM has ended prematurely." % l.id)
         for rr in vmrr.post_rrs:
-            self.slottable.removeReservation(rr)
+            self.slottable.remove_reservation(rr)
         vmrr.post_rrs = []
         # TODO: slideback shutdown RRs
         vmrr.end = get_clock().get_time()



More information about the Haizea-commit mailing list