From 066d9f590f3bee4a65202c181d8e1513e7ba605b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20K=C3=BCnsem=C3=B6ller?= <jkuensem@physik.uni-bielefeld.de> Date: Tue, 28 Sep 2021 18:56:08 +0200 Subject: [PATCH] TMSS-159: further adaptations to new start/stop times, add aggregate time properties, set process times when scheduling --- .../scheduling/lib/dynamic_scheduling.py | 6 +++--- .../src/tmss/tmssapp/models/scheduling.py | 17 +++++++++++++++++ .../src/tmss/tmssapp/serializers/scheduling.py | 2 +- SAS/TMSS/backend/src/tmss/tmssapp/subtasks.py | 4 ++++ .../src/tmss/tmssapp/viewsets/scheduling.py | 8 ++++++-- 5 files changed, 31 insertions(+), 6 deletions(-) diff --git a/SAS/TMSS/backend/services/scheduling/lib/dynamic_scheduling.py b/SAS/TMSS/backend/services/scheduling/lib/dynamic_scheduling.py index 428bc37d3f0..f107a47b8eb 100644 --- a/SAS/TMSS/backend/services/scheduling/lib/dynamic_scheduling.py +++ b/SAS/TMSS/backend/services/scheduling/lib/dynamic_scheduling.py @@ -303,9 +303,9 @@ def get_scheduled_scheduling_units(lower:datetime=None, upper:datetime=None) -> '''get a list of all scheduling_units for which at least one 'independent' (with no predecessor like an observation) subtask is scheduled''' scheduled_subtasks = models.Subtask.independent_subtasks().filter(state__value='scheduled') if lower is not None: - scheduled_subtasks = scheduled_subtasks.filter(stop_time__gte=lower) + scheduled_subtasks = scheduled_subtasks.filter(scheduled_on_sky_stop_time__gte=lower) if upper is not None: - scheduled_subtasks = scheduled_subtasks.filter(start_time__lte=upper) + scheduled_subtasks = scheduled_subtasks.filter(scheduled_on_sky_start_time__lte=upper) return list(models.SchedulingUnitBlueprint.objects.filter(id__in=scheduled_subtasks.values('task_blueprint__scheduling_unit_blueprint_id').distinct()).all()) @@ -314,7 +314,7 @@ def get_running_observation_subtasks(stopping_after:datetime=None) -> [models.Su running_obs_subtasks = models.Subtask.objects.filter(state__value__in=[models.SubtaskState.Choices.STARTING.value, models.SubtaskState.Choices.STARTED.value], specifications_template__type__value=models.SubtaskType.Choices.OBSERVATION.value) if stopping_after is not None: - running_obs_subtasks = running_obs_subtasks.filter(stop_time__gte=stopping_after) + running_obs_subtasks = running_obs_subtasks.filter(scheduled_on_sky_stop_time__gte=stopping_after) return list(running_obs_subtasks.all()) diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/models/scheduling.py b/SAS/TMSS/backend/src/tmss/tmssapp/models/scheduling.py index f474f4d9b20..cf5ef948746 100644 --- a/SAS/TMSS/backend/src/tmss/tmssapp/models/scheduling.py +++ b/SAS/TMSS/backend/src/tmss/tmssapp/models/scheduling.py @@ -21,6 +21,7 @@ from lofar.sas.tmss.tmss.exceptions import SubtaskSchedulingException, SubtaskIl from django.conf import settings from lofar.sas.resourceassignment.resourceassignmentservice.rpc import RADBRPC import uuid +from django.db.models.functions import Coalesce # # I/O @@ -289,6 +290,22 @@ class Subtask(BasicCommon, ProjectPropertyMixin, TemplateSchemaMixin): self.specifications_template.type.value, self.state)) + @property + def on_sky_start_time(self) -> datetime: + return self.scheduled_on_sky_start_time if self.actual_on_sky_start_time is None else self.actual_on_sky_start_time + + @property + def on_sky_stop_time(self) -> datetime: + return self.scheduled_on_sky_stop_time if self.actual_on_sky_stop_time is None else self.actual_on_sky_stop_time + + @property + def process_start_time(self) -> datetime: + return self.scheduled_process_start_time if self.actual_process_start_time is None else self.actual_process_start_time + + @property + def process_stop_time(self) -> datetime: + return self.scheduled_process_stop_time if self.actual_process_stop_time is None else self.actual_process_stop_time + def save(self, force_insert=False, force_update=False, using=None, update_fields=None): creating = self._state.adding # True on create, False on update diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/serializers/scheduling.py b/SAS/TMSS/backend/src/tmss/tmssapp/serializers/scheduling.py index 04a943b9313..e41d21d8c8c 100644 --- a/SAS/TMSS/backend/src/tmss/tmssapp/serializers/scheduling.py +++ b/SAS/TMSS/backend/src/tmss/tmssapp/serializers/scheduling.py @@ -91,7 +91,7 @@ class SubtaskSerializer(DynamicRelationalHyperlinkedModelSerializer): class Meta: model = models.Subtask fields = '__all__' - extra_fields = ['input_dataproducts', 'output_dataproducts'] + extra_fields = ['input_dataproducts', 'output_dataproducts', 'on_sky_start_time', 'on_sky_stop_time', 'process_start_time', 'process_stop_time'] expandable_fields = { 'input_dataproducts': ('lofar.sas.tmss.tmss.tmssapp.serializers.DataproductSerializer', {'many': True}), 'output_dataproducts': ('lofar.sas.tmss.tmss.tmssapp.serializers.DataproductSerializer', {'many': True}) diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/subtasks.py b/SAS/TMSS/backend/src/tmss/tmssapp/subtasks.py index fa1ee8088b4..cf1f3c93157 100644 --- a/SAS/TMSS/backend/src/tmss/tmssapp/subtasks.py +++ b/SAS/TMSS/backend/src/tmss/tmssapp/subtasks.py @@ -1482,6 +1482,10 @@ def schedule_observation_subtask(observation_subtask: Subtask): # step 5: set state to SCHEDULED (resulting in the qaservice to pick this subtask up and run it) observation_subtask.state = SubtaskState.objects.get(value=SubtaskState.Choices.SCHEDULED.value) + + # step 6: set scheduled_process_start/stop_time for MACScheduler + observation_subtask.scheduled_process_start_time = observation_subtask.scheduled_on_sky_start_time - timedelta(minutes=3) + observation_subtask.scheduled_process_stop_time = observation_subtask.scheduled_on_sky_stop_time + timedelta(minutes=1) observation_subtask.save() return observation_subtask diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/scheduling.py b/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/scheduling.py index 18f108dd5cd..f59734365aa 100644 --- a/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/scheduling.py +++ b/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/scheduling.py @@ -39,7 +39,7 @@ from lofar.sas.tmss.tmss.tmssapp.renderers import PlainTextRenderer from rest_framework.views import APIView from rest_framework.decorators import api_view, renderer_classes from django.core.exceptions import ObjectDoesNotExist - +import django_property_filter as property_filters class TextPlainAutoSchema(SwaggerAutoSchema): def get_produces(self): @@ -131,12 +131,16 @@ class DataproductFeedbackTemplateViewSet(AbstractTemplateViewSet): serializer_class = serializers.DataproductFeedbackTemplateSerializer -class SubTaskFilter(filters.FilterSet): +class SubTaskFilter(property_filters.PropertyFilterSet): id = NumberInFilter(field_name='id', lookup_expr='in') id_min = filters.NumberFilter(field_name='id', lookup_expr='gte') id_max = filters.NumberFilter(field_name='id', lookup_expr='lte') state = filters.ModelMultipleChoiceFilter(field_name='state', queryset=models.SubtaskState.objects.all()) name = filters.CharFilter(field_name='task_blueprint__scheduling_unit_blueprint__name', lookup_expr='icontains') # todo: correct name? + on_sky_start_time__lt = property_filters.PropertyDateTimeFilter(field_name='on_sky_start_time', lookup_expr='lt') + on_sky_start_time__gt = property_filters.PropertyDateTimeFilter(field_name='on_sky_start_time', lookup_expr='gt') + process_start_time__lt = property_filters.PropertyDateTimeFilter(field_name='process_start_time', lookup_expr='lt') + process_stop_time__gt = property_filters.PropertyDateTimeFilter(field_name='process_start_time', lookup_expr='gt') class Meta: model = Subtask -- GitLab