diff --git a/SAS/ResourceAssignment/ResourceAssigner/lib/assignment.py b/SAS/ResourceAssignment/ResourceAssigner/lib/assignment.py index d20f2ee94568381dd5624b2bbe4e6b724036603c..afdbdfc10962e80756e6a8805cfe773ac23a9813 100755 --- a/SAS/ResourceAssignment/ResourceAssigner/lib/assignment.py +++ b/SAS/ResourceAssignment/ResourceAssigner/lib/assignment.py @@ -134,7 +134,7 @@ class ResourceAssigner(): @property @cache def resource_group_relations(self): - """ Returns a dict of resource groups and their relations. Does not include resources. + """ Returns a dict of resource groups and their relations. Does not include resources. Each dict element has the resource group id as key, and the following value: @@ -152,7 +152,7 @@ class ResourceAssigner(): return {rt['name']:rt['id'] for rt in self.radbrpc.getResourceTypes()} - + @property @cache def resource_claim_property_types(self): @@ -231,36 +231,39 @@ class ResourceAssigner(): # task has no output clusterName = '' - def applySaneStartEndTime(origStartTime, origEndTime): + def applySaneStartEndTime(): startTime = datetime.utcnow() + timedelta(minutes=3) maxPredecessorEndTime = self.getMaxPredecessorEndTime(specification_tree) if maxPredecessorEndTime and maxPredecessorEndTime > startTime: startTime = maxPredecessorEndTime + timedelta(minutes=3) - taskDuration = timedelta(seconds=totalSeconds(origEndTime - origStartTime)) if origEndTime > origStartTime else timedelta(hours=1) + taskDuration = mainParset.getInt('Observation.Scheduler.taskDuration', -1) + taskDuration = timedelta(seconds=taskDuration) if taskDuration > 0 else timedelta(hours=1) endTime = startTime + taskDuration logger.warning('Applying sane defaults (%s, %s) for start/end time from specification for otdb_id=%s', - startTime, endTime, otdb_id) + startTime, endTime, otdb_id) - logger.info('uploading auto-generated start/end time (%s, %s) to otdb for otdb_id=%s', startTime, endTime, otdb_id) - self.otdbrpc.taskSetSpecification(otdb_id, { 'LOFAR.ObsSW.Observation.startTime': startTime.strftime('%Y-%m-%d %H:%M:%S'), - 'LOFAR.ObsSW.Observation.stopTime': endTime.strftime('%Y-%m-%d %H:%M:%S')}) - return startTime, endTime + try: + logger.info('uploading auto-generated start/end time (%s, %s) to otdb for otdb_id=%s', startTime, endTime, otdb_id) + self.otdbrpc.taskSetSpecification(otdb_id, { 'LOFAR.ObsSW.Observation.startTime': startTime.strftime('%Y-%m-%d %H:%M:%S'), + 'LOFAR.ObsSW.Observation.stopTime': endTime.strftime('%Y-%m-%d %H:%M:%S')}) + except Exception as e: + logger.error(e) + return startTime, endTime - # TODO: don't fix this crap here. Bad start/stop time has to go to error, like any other bad spec part. Fix the cause! Idem for MoM fix up below. try: startTime = parseDatetime(mainParset.getString('Observation.startTime')) endTime = parseDatetime(mainParset.getString('Observation.stopTime')) if startTime < datetime.utcnow(): - startTime, endTime = applySaneStartEndTime(startTime, endTime) - except Exception as e: - logger.error(str(e)) - return + startTime, endTime = applySaneStartEndTime() + except Exception: + logger.warning('cannot parse for start/end time from specification for otdb_id=%s. searching for sane defaults...', otdb_id) + startTime, endTime = applySaneStartEndTime() logger.info('doAssignment: Accepted specification') @@ -544,10 +547,10 @@ class ResourceAssigner(): def findClaims(self, needed_resources_list, db_resource_list): """ Compute claims that satisfy needed_resources_list within db_resource_list. - + :param needed_resources_list: a list of resources to be claimed :param db_resource_list: all resources in RADB with availability information - + :returns all_fit: a boolean indicating whether all requested resources could be claimed :returns claims: all claims that succeeded (partial if all_fit is False) :returns unclaimable_resources: all resources from needed_resources_list that could not be claimed ([] if all_fit is True) @@ -748,12 +751,12 @@ class ResourceAssigner(): def is_claimable_capacity_wise(self, needed_resources, claimable_resources, ignore_type_ids=None): """ Returns whether all needed_resources can be claimed from claimable_resources. - + :param needed_resources: {resource_type_id: size, ...} :param claimable_resources: {resource_type_id: {<resource_dict>}, ...} :param ignore_type_ids: IDs of types that should not be considered - - + + """ types_to_ignore = ignore_type_ids if ignore_type_ids is not None else []