diff --git a/SAS/TMSS/backend/services/scheduling/lib/dynamic_scheduling.py b/SAS/TMSS/backend/services/scheduling/lib/dynamic_scheduling.py index 9c0957cd494bc13a1d5f2cb85bee8a5719c83cb4..6902fa504691f06c84ac187aa5b75a0364041067 100644 --- a/SAS/TMSS/backend/services/scheduling/lib/dynamic_scheduling.py +++ b/SAS/TMSS/backend/services/scheduling/lib/dynamic_scheduling.py @@ -327,7 +327,7 @@ class Scheduler: # when new candidates are overlapping with already scheduled units, they are re-evaluated to see who wins. to_be_excluded_units = set(scheduled_units) - set(get_dynamically_schedulable_scheduling_units().all()) scheduled_unit = self.schedule_next_scheduling_unit(lower_bound, - lower_bound + timedelta(hours=24), + min(lower_bound + timedelta(hours=24), upper_bound), exclude_units=to_be_excluded_units) if scheduled_unit: @@ -340,22 +340,8 @@ class Scheduler: scheduled_B_units = self.schedule_B_priority_units_in_gaps_around_scheduling_unit(scheduled_unit) scheduled_units.extend(scheduled_B_units) else: - # nothing was scheduled in the window lower_bound+24h, so advance and see if anything fits - # check for any overlapping units... - blocking_units = models.SchedulingUnitBlueprint.objects.filter( - obsolete_since__isnull=True).filter( - status__value__in=(models.SchedulingUnitStatus.Choices.SCHEDULED.value, - models.SchedulingUnitStatus.Choices.OBSERVING.value)).filter( - on_sky_stop_time__gte=lower_bound).filter( - on_sky_stop_time__lte=lower_bound + timedelta(hours=24)) - - if blocking_units.exists(): - # advance beyond the blocking unit(s) - max_blocking_stop_time = blocking_units.aggregate(Max('on_sky_stop_time'))['on_sky_stop_time__max'] - lower_bound = max(max_blocking_stop_time + DEFAULT_INTER_OBSERVATION_GAP, lower_bound + timedelta(hours=1)) - else: - # just advance - lower_bound += timedelta(hours=3) + # advance window and search again + lower_bound += timedelta(hours=2) # for nice "visual" feedback to the user, move each "old" schedulable unit to the lower_bound # this also indicates to the user that the unit has been considered for times < lower_bound, and they could not be scheduled there. @@ -647,7 +633,7 @@ class Scheduler: # make start_time "look nice" for us humans best_start_time = round_to_second_precision(best_start_time) - logger.info("schedule_next_scheduling_unit: found best candidate id=%s '%s' weighted_score=%.3f start_time=%s interrupts_telescope=%s queue=%s", + logger.info("schedule_next_scheduling_unit: found best candidate id=%s '%s' weighted_score=%.4f start_time=%s interrupts_telescope=%s queue=%s", best_scheduling_unit.id, best_scheduling_unit.name, best_scheduling_unit_score, best_start_time, best_scheduling_unit.interrupts_telescope, best_scheduling_unit.priority_queue.value) scheduled_unit = self.try_schedule_unit(best_scheduling_unit, best_start_time) @@ -737,8 +723,12 @@ class Scheduler: blocking_scheduling_units = get_blocking_scheduled_or_observing_units(scheduling_unit, start_time) if blocking_scheduling_units.exists(): - logger.warning("cannot schedule scheduling_unit id=%s '%s' at start_time=%s interrupts_telescope=%s because there are %d other units blocking it", - scheduling_unit.id, scheduling_unit.name, start_time, scheduling_unit.interrupts_telescope, blocking_scheduling_units.count()) + logger.warning("cannot schedule scheduling_unit id=%s '%s' at start_time=%s interrupts_telescope=%s because there %s %d other unit%s blocking it: %s", + scheduling_unit.id, scheduling_unit.name, start_time, scheduling_unit.interrupts_telescope, + "is" if blocking_scheduling_units.count()==1 else "else", + blocking_scheduling_units.count(), + "" if blocking_scheduling_units.count()==1 else "s", + ",".join([str(bsu.id) for bsu in blocking_scheduling_units])) return None with transaction.atomic(): @@ -1286,6 +1276,7 @@ def get_fixed_time_schedulable_scheduling_units() -> QuerySet: scheduling_units = models.SchedulingUnitBlueprint.objects.filter(status__value=models.SchedulingUnitStatus.Choices.SCHEDULABLE.value).filter(obsolete_since__isnull=True) scheduling_units = scheduling_units.filter(scheduling_constraints_template__name='constraints') scheduling_units = scheduling_units.filter(scheduling_constraints_doc__scheduler='fixed_time') + scheduling_units = scheduling_units.order_by('-updated_at') return scheduling_units @@ -1429,7 +1420,7 @@ def unschededule_blocking_scheduled_units_if_needed_and_possible(candidate_sched scheduled_scheduling_unit.id, scheduled_scheduling_unit.name, scheduled_scheduling_unit.scheduled_start_time, rescored_scheduled_unit.weighted_score, rescored_candidate.scheduling_unit.id, rescored_candidate.scheduling_unit.name, rescored_candidate.start_time, rescored_candidate.weighted_score) - logger.info("the scheduled unit id=%s '%s' score=%.3f is in the way of the best candidate id=%s '%s' score=%.3f start_time=%s", + logger.info("the scheduled unit id=%s '%s' score=%.5f is in the way of the best candidate id=%s '%s' score=%.5f start_time=%s", scheduled_scheduling_unit.id, scheduled_scheduling_unit.name, rescored_scheduled_unit.weighted_score, candidate_scheduling_unit.id, candidate_scheduling_unit.name, rescored_candidate.weighted_score, candidate_scheduling_unit.scheduled_start_time)