[haizea-commit] r786 - branches/1.1/src/haizea/core/scheduler
haizea-commit at mailman.cs.uchicago.edu
haizea-commit at mailman.cs.uchicago.edu
Wed Jan 20 20:40:55 CST 2010
Author: borja
Date: 2010-01-20 20:40:55 -0600 (Wed, 20 Jan 2010)
New Revision: 786
Modified:
branches/1.1/src/haizea/core/scheduler/lease_scheduler.py
Log:
Reschedule leases after a premature end
Modified: branches/1.1/src/haizea/core/scheduler/lease_scheduler.py
===================================================================
--- branches/1.1/src/haizea/core/scheduler/lease_scheduler.py 2010-01-21 02:40:28 UTC (rev 785)
+++ branches/1.1/src/haizea/core/scheduler/lease_scheduler.py 2010-01-21 02:40:55 UTC (rev 786)
@@ -38,6 +38,7 @@
from operator import attrgetter
import logging
+from mx.DateTime import DateTimeDelta
class LeaseScheduler(object):
"""The Haizea Lease Scheduler
@@ -490,58 +491,79 @@
# scenario is that it simply replicates the previous schedule)
self.__schedule_lease(l, nexttime)
+ numnodes = ending_lease.numnodes
+ freetime = ending_lease.duration.requested - ending_lease.duration.accumulated
+ until = nexttime + freetime
+ freecapacity = numnodes * freetime
+ print "Freeing up %i nodes for %s from lease %i" % (numnodes, freetime, ending_lease.id)
+
future_vmrrs = self.slottable.get_reservations_on_or_after(nexttime)
future_vmrrs.sort(key=attrgetter("start"))
future_vmrrs = [rr for rr in future_vmrrs
if isinstance(rr, VMResourceReservation)
and rr.lease.get_type() == Lease.DEADLINE
- and rr.lease.get_state() in (Lease.STATE_SCHEDULED, Lease.STATE_READY, Lease.STATE_SUSPENDED_SCHEDULED)]
+ and rr.lease.get_state() in (Lease.STATE_SCHEDULED, Lease.STATE_READY)
+ and not rr.is_suspending() and not rr.is_resuming()]
leases = list(set([future_vmrr.lease for future_vmrr in future_vmrrs]))
+ leases = [l for l in leases if l.numnodes <= numnodes
+ and l.start.requested <= until
+ and l.duration.requested <= min(freetime, until - l.start.requested)]
+ leases.sort(key= lambda l: (l.deadline - nexttime) / l.duration.requested)
+ self.logger.debug("Rescheduling future deadline leases")
- leases.sort(key= lambda l: (l.deadline - nexttime) / l.get_remaining_duration_at(nexttime))
- if len(leases) > 0:
- self.logger.debug("Rescheduling future deadline leases")
- #self.slottable.push_state(leases)
- feasible = True
- node_ids = self.slottable.nodes.keys()
- earliest = {}
- for node in node_ids:
- earliest[node] = EarliestStartingTime(nexttime, EarliestStartingTime.EARLIEST_NOPREPARATION)
-
- orig_vmrrs = dict([(l,[rr for rr in future_vmrrs if rr.lease == l]) for l in leases])
- dirtynodes = ending_lease.get_last_vmrr().resources_in_pnode.keys()
-
- dirtynodes, cleanleases = self.vm_scheduler.find_dirty_nodes(leases, dirtynodes, orig_vmrrs)
-
- dirtyleases = [l for l in leases if l not in cleanleases]
-
- print "Would have to reschedule %i leases" % len(dirtyleases)
- return
-
- for vmrr in [vmrr2 for vmrr2 in future_vmrrs if vmrr2.lease not in cleanleases]:
- self.vm_scheduler.cancel_vm(vmrr)
+ filled = DateTimeDelta(0)
+ for l in leases:
+ dur = min(until - l.start.requested, l.duration.requested)
+ capacity = l.numnodes * dur
+
+ if filled + capacity <= freecapacity:
+ # This lease might fit
+ self.logger.debug("Trying to reschedule lease %i" % l.id)
+ self.slottable.push_state([l])
+ node_ids = self.slottable.nodes.keys()
+ earliest = {}
+ for node in node_ids:
+ earliest[node] = EarliestStartingTime(nexttime, EarliestStartingTime.EARLIEST_NOPREPARATION)
+ for vmrr in [vmrr2 for vmrr2 in future_vmrrs if vmrr2.lease == l]:
+ vmrr.lease.remove_vmrr(vmrr)
+ self.vm_scheduler.cancel_vm(vmrr)
- try:
- (scheduled, add_vmrrs, dirtytime) = self.vm_scheduler.reschedule_deadline_leases(dirtyleases, orig_vmrrs, nexttime, earliest, nexttime, dirtytime=None)
- except NotSchedulableException:
- self.logger.debug("Future leases could not be rescheduled, undoing changes.")
- feasible = False
-
- if feasible:
- self.slottable.pop_state(discard=True)
- for l in [l2 for l2 in orig_vmrrs if l2 in scheduled]:
- for vmrr in orig_vmrrs[l]:
- vmrr.lease.remove_vmrr(vmrr)
+ try:
+ origd = l.deadline
+ l.deadline = until
+ (new_vmrr, preemptions) = self.vm_scheduler.reschedule_deadline(l, dur, nexttime, earliest)
+ l.deadline = origd
- for lease2, vmrr in add_vmrrs.items():
- lease2.append_vmrr(vmrr)
- else:
- self.slottable.pop_state()
+ # Add VMRR to lease
+ l.append_vmrr(new_vmrr)
+
+ # Add resource reservations to slottable
+
+ # Pre-VM RRs (if any)
+ for rr in new_vmrr.pre_rrs:
+ self.slottable.add_reservation(rr)
+
+ # VM
+ self.slottable.add_reservation(new_vmrr)
+
+ # Post-VM RRs (if any)
+ for rr in new_vmrr.post_rrs:
+ self.slottable.add_reservation(rr)
+
+ self.logger.debug("Rescheduled lease %i" % l.id)
+ self.logger.vdebug("Lease after rescheduling:")
+ l.print_contents()
+
+ filled += capacity
+
+ self.slottable.pop_state(discard=True)
+ except NotSchedulableException:
+ l.deadline = origd
+ self.logger.debug("Lease %i could not be rescheduled" % l.id)
+ self.slottable.pop_state()
-
-
def is_queue_empty(self):
"""Return True is the queue is empty, False otherwise"""
return self.queue.is_empty()
@@ -831,11 +853,7 @@
l.set_state(Lease.STATE_DONE)
l.duration.actual = l.duration.accumulated
l.end = round_datetime(get_clock().get_time())
- self.preparation_scheduler.cleanup(l)
- self.completed_leases.add(l)
- self.leases.remove(l)
- self.accounting.at_lease_done(l)
-
+
if get_config().get("sanity-check"):
if l.duration.known != None and l.duration.known < l.duration.requested:
duration = l.duration.known
@@ -843,7 +861,18 @@
duration = l.duration.requested
assert duration == l.duration.actual
+
+ if l.start.is_requested_exact():
+ assert l.vm_rrs[0].start >= l.start.requested
+ if l.deadline != None:
+ assert l.end <= l.deadline
+
+ self.preparation_scheduler.cleanup(l)
+ self.completed_leases.add(l)
+ self.leases.remove(l)
+ self.accounting.at_lease_done(l)
+
More information about the Haizea-commit
mailing list