diff --git a/SAS/ResourceAssignment/ResourceAssigner/lib/assignment.py b/SAS/ResourceAssignment/ResourceAssigner/lib/assignment.py index cb9149a72e5e78c16593cbcc33a9dd54df365aaa..d55fcc996a592323c8ebb5a4db4b36e08d587d91 100755 --- a/SAS/ResourceAssignment/ResourceAssigner/lib/assignment.py +++ b/SAS/ResourceAssignment/ResourceAssigner/lib/assignment.py @@ -313,7 +313,7 @@ class ResourceAssigner(): # Also, inserted claims are still automatically validated, there can be a race. # If not enough resources are available after all, claims are put to conflict status. # If any claim is in conflict state, then the task is put to conflict status as well. - claims = self.getClaimsForTask(task, estimates, db_resource_list, db_rgp2rgp, db_resource_types, + claims = self.getClaimsForTask(task, estimates, db_resource_list, db_resource_claims_rcus, db_rgp2rgp, db_resource_types, db_resource_prop_types) if claims is None: self._sendStateChange(task, 'error') @@ -479,7 +479,7 @@ class ResourceAssigner(): res['available_capacity'] = min(res['available_capacity'], int(ratio * res['total_capacity'])) logger.info('applyMaxFillRatios: applied %s = %f', ratio_dict['name'], ratio) - def getClaimsForTask(self, task, needed_resources_list, db_resource_list, + def getClaimsForTask(self, task, needed_resources_list, db_resource_list, db_resource_claims_rcus, db_rgp2rgp, db_resource_types, db_resource_prop_types): """ Return claims that satisfy needed_resources_list within db_resource_list, or an empty claim list if no non-conflicting claims could be found, or None on error. @@ -487,6 +487,7 @@ class ResourceAssigner(): :param task: an instance of an RADB task object :param needed_resources_list: a list of resources to be claimed :param db_resource_list: all resources in RADB with availability information + :param db_resource_claims_rcus: all claims on RCUs :param db_rgp2rgp: all group->group relations from RADB :param db_resource_types: all virtual instrument resource types (and their units) from RADB :param db_resource_prop_types: all resource claim property types from RADB @@ -513,6 +514,7 @@ class ResourceAssigner(): logger.debug('getClaimsForTask: db_rgp2rgp: %s', db_rgp2rgp) # big! logger.debug('getClaimsForTask: db_resource_list: %s', db_resource_list) # big! + logger.debug('getClaimsForTask: db_resource_claims_rcus: %s', db_resource_claims_rcus) # big! logger.debug('getClaimsForTask: db_resource_types: %s', db_resource_types) logger.debug('getClaimsForTask: db_resource_prop_types: %s', db_resource_prop_types) @@ -569,12 +571,13 @@ class ResourceAssigner(): # Almost always iterates once. Still needed to match >1 resource types. claim = None for claimable_resources_dict in claimable_resources_list: + # Ignore check on claimable capacity of RCUs is_claimable = self.is_claimable_capacity_wise(needed_resources_by_type_id, claimable_resources_dict, ignore_type_ids=[db_rcu_type_id]) is_claimable &= self.is_claimable_rcu_wise(needed_resources_by_type_id, - claimable_resources_dict, + db_resource_claims_rcus, db_rcu_type_id) if is_claimable: @@ -650,17 +653,27 @@ class ResourceAssigner(): """ types_to_ignore = ignore_type_ids if ignore_type_ids is not None else [] - is_claimable = all(claim_size <= claimable_resources[res_type]['available_capacity'] \ + is_claimable = all(claim_size <= claimable_resources[res_type]['available_capacity'] for res_type, claim_size in needed_resources.items() if res_type not in types_to_ignore) return is_claimable - # TODO: implement this function! - def is_claimable_rcu_wise(self, needed_resources, claimable_resources, rcu_resource_type_id): + # TODO: (Ruud B) Verify if this function makes any sense! I get the feeling that start/end-times need to be + # considered, because 'resource_claims_rcus' might hold RCU-claims that are outside our time-period of interest + def is_claimable_rcu_wise(self, needed_resources, resource_claims_rcus, rcu_resource_type_id): is_claimable = True - # is_claimable &= all(used_rcus <= claimable_resources[res_type]['used_rcus'] \ - # for res_type, used_rcus in needed_resources.items() if res_type == rcu_resource_type_id) + for res_type, used_rcus in needed_resources.items(): + if res_type == rcu_resource_type_id: + for claimed_rcus in resource_claims_rcus['used_rcus']: + length_difference = abs(len(claimed_rcus) - len(used_rcus)) + if len(claimed_rcus) < len(used_rcus): + claimed_rcus.ljust(length_difference, '0') + elif len(claimed_rcus) > len(used_rcus): + used_rcus.ljust(length_difference, '0') + + is_claimable &= all(not (int(used_rcus[idx]) & int(character)) + for idx, character in enumerate(claimed_rcus)) return is_claimable