Skip to content
Snippets Groups Projects
Commit 7536be9c authored by Jorrit Schaap's avatar Jorrit Schaap
Browse files

Task #10811 and #9893: merged feature branch 10811 back into rt-trunk

parents 3659185b 2e664f58
No related branches found
No related tags found
No related merge requests found
...@@ -424,6 +424,13 @@ class RADatabase: ...@@ -424,6 +424,13 @@ class RADatabase:
return self.cursor.rowcount > 0 return self.cursor.rowcount > 0
def updateTask(self, task_id, mom_id=None, otdb_id=None, task_status=None, task_type=None, specification_id=None, commit=True): def updateTask(self, task_id, mom_id=None, otdb_id=None, task_status=None, task_type=None, specification_id=None, commit=True):
'''Update the given paramenters for the task with given task_id.
Inside the database consistency checks are made.
When one or more claims of a task are in conflict status, then its task is set to conflict as well, and hence cannot be scheduled.
When all claims of a task are not in conflict status anymore, then the task is set to approved, and hence it is possible the schedule the task.
When a task is unscheduled (set to approved) then the claimed claims are set to tentative.
'''
task_status, task_type = self._convertTaskTypeAndStatusToIds(task_status, task_type) task_status, task_type = self._convertTaskTypeAndStatusToIds(task_status, task_type)
fields = [] fields = []
...@@ -1265,6 +1272,16 @@ class RADatabase: ...@@ -1265,6 +1272,16 @@ class RADatabase:
def updateResourceClaims(self, where_resource_claim_ids=None, where_task_ids=None, resource_id=None, task_id=None, starttime=None, endtime=None, def updateResourceClaims(self, where_resource_claim_ids=None, where_task_ids=None, resource_id=None, task_id=None, starttime=None, endtime=None,
status=None, claim_size=None, username=None, used_rcus=None, user_id=None, status=None, claim_size=None, username=None, used_rcus=None, user_id=None,
commit=True): commit=True):
'''Update the given paramenters on all resource claims given/delimited by where_resource_claim_ids and/or where_task_ids.
Inside the database consistency checks are made. For example, in case you want to set a claim's status to 'claimed', but it does not fit in the free capacity of the claim's resource, then the claim goes to 'conflict'.
A claim fits, (and hence can be claimed) only if the claim_size < resource.free_capacity within the claims time window.
When a claim is released (claimed->tentative) then all overlapping conflicting claims are checked again if they fit because there is more capacity available.
When a claim is claimed (tentative->claimed) then all overlapping tentative claims are checked again if they still fit because there is less capacity available.
When one or more claims of a task are in conflict status, then its task is set to conflict as well, and hence cannot be scheduled.
When all claims of a task are not in conflict status anymore, then the task is set to approved, and hence it is possible the schedule the task.
'''
logger.info("updateResourceClaims") logger.info("updateResourceClaims")
status_id = status status_id = status
...@@ -1347,6 +1364,7 @@ class RADatabase: ...@@ -1347,6 +1364,7 @@ class RADatabase:
def updateTaskAndResourceClaims(self, task_id, starttime=None, endtime=None, task_status=None, claim_status=None, username=None, used_rcus=None, user_id=None, commit=True): def updateTaskAndResourceClaims(self, task_id, starttime=None, endtime=None, task_status=None, claim_status=None, username=None, used_rcus=None, user_id=None, commit=True):
'''combination of updateResourceClaims and updateTask in one transaction'''
updated = True updated = True
if (starttime or endtime or claim_status is not None or if (starttime or endtime or claim_status is not None or
......
...@@ -391,6 +391,7 @@ BEGIN ...@@ -391,6 +391,7 @@ BEGIN
WHERE ru.resource_id = old_claim.resource_id WHERE ru.resource_id = old_claim.resource_id
AND ru.status_id = old_claim.status_id AND ru.status_id = old_claim.status_id
AND ru.as_of_timestamp < old_claim.starttime AND ru.as_of_timestamp < old_claim.starttime
ORDER BY ru.as_of_timestamp DESC
LIMIT 1 LIMIT 1
INTO usage_before_start; INTO usage_before_start;
...@@ -517,7 +518,7 @@ BEGIN ...@@ -517,7 +518,7 @@ BEGIN
-- this function is quite similar to resource_allocation.get_conflicting_overlapping_claims -- this function is quite similar to resource_allocation.get_conflicting_overlapping_claims
-- for performance reasons we repeat the common code here instead of wrapping the common code in a function -- for performance reasons we repeat the common code here instead of wrapping the common code in a function
--get all overlapping_claims, whether they cause a conflict or not. --get all overlapping_claims, check whether they cause a conflict or not.
SET LOCAL client_min_messages=warning; --prevent "table overlapping_claims does not exist, skipping" message SET LOCAL client_min_messages=warning; --prevent "table overlapping_claims does not exist, skipping" message
DROP TABLE IF EXISTS overlapping_claims; -- TODO: use CREATE TEMPORARY TABLE IF NOT EXISTS when we will use postgres 9.5+ DROP TABLE IF EXISTS overlapping_claims; -- TODO: use CREATE TEMPORARY TABLE IF NOT EXISTS when we will use postgres 9.5+
CREATE TEMPORARY TABLE overlapping_claims CREATE TEMPORARY TABLE overlapping_claims
...@@ -527,13 +528,14 @@ BEGIN ...@@ -527,13 +528,14 @@ BEGIN
AND rc.status_id = claim_claimed_status_id AND rc.status_id = claim_claimed_status_id
AND rc.id <> claim.id AND rc.id <> claim.id
AND rc.endtime >= claim.starttime AND rc.endtime >= claim.starttime
AND rc.starttime <= claim.endtime; AND rc.starttime < claim.endtime;
--get the full time window of the overlapping claims --get the full time window of the overlapping claims
SELECT min(starttime) FROM overlapping_claims INTO overlapping_claims_min_starttime; SELECT min(starttime) FROM overlapping_claims INTO overlapping_claims_min_starttime;
SELECT max(starttime) FROM overlapping_claims INTO overlapping_claims_max_endtime; SELECT max(endtime) FROM overlapping_claims INTO overlapping_claims_max_endtime;
-- get the free free_claimable_capacity for this resource for the full overlapping claim time window -- get the free free_claimable_capacity for this resource for the full overlapping claim time window
-- this does not include the current claim which is (or at least should be) tentative.
SELECT * FROM resource_allocation.get_resource_claimable_capacity_between(claim.resource_id, overlapping_claims_min_starttime, overlapping_claims_max_endtime) INTO free_claimable_capacity; SELECT * FROM resource_allocation.get_resource_claimable_capacity_between(claim.resource_id, overlapping_claims_min_starttime, overlapping_claims_max_endtime) INTO free_claimable_capacity;
return claim.claim_size > free_claimable_capacity; return claim.claim_size > free_claimable_capacity;
...@@ -541,7 +543,7 @@ END; ...@@ -541,7 +543,7 @@ END;
$$ LANGUAGE plpgsql; $$ LANGUAGE plpgsql;
ALTER FUNCTION resource_allocation.has_conflict_with_overlapping_claims(claim resource_allocation.resource_claim) OWNER TO resourceassignment; ALTER FUNCTION resource_allocation.has_conflict_with_overlapping_claims(claim resource_allocation.resource_claim) OWNER TO resourceassignment;
COMMENT ON FUNCTION resource_allocation.has_conflict_with_overlapping_claims(claim resource_allocation.resource_claim) COMMENT ON FUNCTION resource_allocation.has_conflict_with_overlapping_claims(claim resource_allocation.resource_claim)
IS 'helper function which is called by resource_claim table insert and update triggers, which checks if the new claim fits in the free capacity of its resource.'; IS 'checks if the claim fits in the free capacity of its resource.';
--------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------
...@@ -574,7 +576,7 @@ BEGIN ...@@ -574,7 +576,7 @@ BEGIN
-- this function is quite similar to resource_allocation.has_conflict_with_overlapping_claims -- this function is quite similar to resource_allocation.has_conflict_with_overlapping_claims
-- for performance reasons we repeat the common code here instead of wrapping the common code in a function -- for performance reasons we repeat the common code here instead of wrapping the common code in a function
--get all overlapping_claims, whether they cause a conflict or not. --get all overlapping_claims, check whether they cause a conflict or not.
SET LOCAL client_min_messages=warning; --prevent "table overlapping_claims does not exist, skipping" message SET LOCAL client_min_messages=warning; --prevent "table overlapping_claims does not exist, skipping" message
DROP TABLE IF EXISTS overlapping_claims; -- TODO: use CREATE TEMPORARY TABLE IF NOT EXISTS when we will use postgres 9.5+ DROP TABLE IF EXISTS overlapping_claims; -- TODO: use CREATE TEMPORARY TABLE IF NOT EXISTS when we will use postgres 9.5+
CREATE TEMPORARY TABLE overlapping_claims CREATE TEMPORARY TABLE overlapping_claims
...@@ -584,7 +586,7 @@ BEGIN ...@@ -584,7 +586,7 @@ BEGIN
AND rc.status_id = claim_claimed_status_id AND rc.status_id = claim_claimed_status_id
AND rc.id <> claim.id AND rc.id <> claim.id
AND rc.endtime >= claim.starttime AND rc.endtime >= claim.starttime
AND rc.starttime <= claim.endtime; AND rc.starttime < claim.endtime;
RETURN QUERY SELECT * RETURN QUERY SELECT *
FROM overlapping_claims oc FROM overlapping_claims oc
...@@ -630,7 +632,7 @@ BEGIN ...@@ -630,7 +632,7 @@ BEGIN
END IF; END IF;
IF TG_OP = 'INSERT' OR TG_OP = 'UPDATE' THEN IF TG_OP = 'INSERT' OR TG_OP = 'UPDATE' THEN
--only check claim if in tentative/conflict status, and status or start/end time changed --only check claim if in tentative/conflict status, and status or claim_size or start/end time changed
IF NEW.status_id = claim_tentative_status_id OR NEW.status_id = claim_conflict_status_id THEN IF NEW.status_id = claim_tentative_status_id OR NEW.status_id = claim_conflict_status_id THEN
IF TG_OP = 'INSERT' OR (TG_OP = 'UPDATE' AND (OLD.status_id <> NEW.status_id OR IF TG_OP = 'INSERT' OR (TG_OP = 'UPDATE' AND (OLD.status_id <> NEW.status_id OR
OLD.claim_size <> NEW.claim_size OR OLD.claim_size <> NEW.claim_size OR
...@@ -712,14 +714,14 @@ BEGIN ...@@ -712,14 +714,14 @@ BEGIN
-- if this claim was moved or went from claimed to other status -- if this claim was moved or went from claimed to other status
-- then check all other claims in conflict which might be affected by this change -- then check all other claims in conflict which might be affected by this change
-- maybe they can be updated from conflict status to tentative... -- maybe they can be updated from conflict status to tentative...
IF (TG_OP = 'UPDATE' AND (OLD.status_id = claim_claimed_status_id OR OLD.starttime <> NEW.starttime OR OLD.endtime <> NEW.endtime)) OR IF (TG_OP = 'UPDATE' AND (OLD.status_id = claim_claimed_status_id OR OLD.starttime <> NEW.starttime OR OLD.endtime <> NEW.endtime OR OLD.claim_size <> NEW.claim_size)) OR
TG_OP = 'DELETE' THEN TG_OP = 'DELETE' THEN
FOR affected_claim IN SELECT * FROM resource_allocation.resource_claim rc FOR affected_claim IN SELECT * FROM resource_allocation.resource_claim rc
WHERE rc.resource_id = OLD.resource_id WHERE rc.resource_id = OLD.resource_id
AND rc.status_id = claim_conflict_status_id AND rc.status_id = claim_conflict_status_id
AND rc.id <> OLD.id AND rc.id <> OLD.id
AND rc.endtime >= OLD.starttime AND rc.endtime >= OLD.starttime
AND rc.starttime <= OLD.endtime LOOP AND rc.starttime < OLD.endtime LOOP
--check if claim fits or has conflicts --check if claim fits or has conflicts
SELECT * FROM resource_allocation.has_conflict_with_overlapping_claims(affected_claim) INTO claim_has_conflicts; SELECT * FROM resource_allocation.has_conflict_with_overlapping_claims(affected_claim) INTO claim_has_conflicts;
...@@ -734,13 +736,13 @@ BEGIN ...@@ -734,13 +736,13 @@ BEGIN
-- if this claim went from to claimed status -- if this claim went from to claimed status
-- then check all other claims in tentative state which might be affected by this change -- then check all other claims in tentative state which might be affected by this change
-- maybe they should be updated from tentative status to conflict... -- maybe they should be updated from tentative status to conflict...
IF TG_OP = 'UPDATE' AND NEW.status_id = claim_claimed_status_id AND OLD.status_id <> NEW.status_id THEN IF TG_OP = 'UPDATE' AND NEW.status_id = claim_claimed_status_id AND (OLD.status_id <> NEW.status_id OR OLD.claim_size <> NEW.claim_size)THEN
FOR affected_claim IN SELECT * FROM resource_allocation.resource_claim rc FOR affected_claim IN SELECT * FROM resource_allocation.resource_claim rc
WHERE rc.resource_id = NEW.resource_id WHERE rc.resource_id = NEW.resource_id
AND rc.status_id = claim_tentative_status_id AND rc.status_id = claim_tentative_status_id
AND rc.id <> NEW.id AND rc.id <> NEW.id
AND rc.endtime >= NEW.starttime AND rc.endtime >= NEW.starttime
AND rc.starttime <= NEW.endtime LOOP AND rc.starttime < NEW.endtime LOOP
--check if claim fits or has conflicts --check if claim fits or has conflicts
SELECT * FROM resource_allocation.has_conflict_with_overlapping_claims(affected_claim) INTO claim_has_conflicts; SELECT * FROM resource_allocation.has_conflict_with_overlapping_claims(affected_claim) INTO claim_has_conflicts;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment