Skip to content

Commit 02a30df

Browse files
committed
Replace Deployment update steps joins with lazy subquery
1 parent 6b7213c commit 02a30df

2 files changed

Lines changed: 62 additions & 3 deletions

File tree

rest-service/manager_rest/storage/resource_models.py

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2025,7 +2025,7 @@ def to_response(self, include=None, **kwargs):
20252025
dep_update_dict = super(DeploymentUpdate, self).to_response(
20262026
include, **kwargs)
20272027
if 'steps' in include:
2028-
dep_update_dict['steps'] = [step.to_dict() for step in self.steps]
2028+
dep_update_dict['steps'] = self.steps
20292029
if 'recursive_dependencies' in include:
20302030
dep_update_dict['recursive_dependencies'] = \
20312031
self.recursive_dependencies
@@ -2057,8 +2057,10 @@ class DeploymentUpdateStep(SQLResourceBase):
20572057
@declared_attr
20582058
def deployment_update(cls):
20592059
return one_to_many_relationship(
2060-
cls, DeploymentUpdate, cls._deployment_update_fk,
2061-
backref=db.backref('steps', cascade='all'))
2060+
cls,
2061+
DeploymentUpdate,
2062+
cls._deployment_update_fk,
2063+
)
20622064

20632065
deployment_update_id = association_proxy('deployment_update', 'id')
20642066

@@ -2091,6 +2093,43 @@ def __lt__(self, other):
20912093
return False
20922094

20932095

2096+
# Define the steps as a property of the DeploymentUpdate
2097+
# It is required to define it here after DeploymentUpdateStep
2098+
# is loaded by SQLAlchemy.
2099+
# In big deployments with lots of steps standard JOIN causes
2100+
# OOMKilled error on pod running by Kubernetes.
2101+
# This declaration adds a custom property that executes lazy select query.
2102+
# The goal of this is to mitigate memory consumption issue.
2103+
DeploymentUpdate.steps = db.column_property(
2104+
db.cast(
2105+
db.func.array(
2106+
2107+
db.select([
2108+
db.func.jsonb_build_object(
2109+
'id', DeploymentUpdateStep.id,
2110+
'action', DeploymentUpdateStep.action,
2111+
'entity_id', DeploymentUpdateStep.entity_id,
2112+
'entity_type', DeploymentUpdateStep.entity_type,
2113+
2114+
'topology_order', DeploymentUpdateStep.topology_order,
2115+
'private_resource', DeploymentUpdateStep.private_resource,
2116+
2117+
'visibility', DeploymentUpdateStep.visibility,
2118+
2119+
)
2120+
])
2121+
.where(
2122+
DeploymentUpdateStep._deployment_update_fk ==
2123+
DeploymentUpdate._storage_id
2124+
)
2125+
2126+
),
2127+
db.ARRAY(db.JSON),
2128+
).label('steps')
2129+
2130+
)
2131+
2132+
20942133
class DeploymentModification(CreatedAtMixin, SQLResourceBase):
20952134
__tablename__ = 'deployment_modifications'
20962135

tests/integration_tests/tests/agentless_tests/test_deployment_workflows.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,23 @@ def test_delete_botched_deployment(self):
128128
self.fail("Expected deployment to be deleted")
129129
except CloudifyClientError as e:
130130
self.assertEqual(404, e.status_code)
131+
132+
def test_deployment_workflows_update_steps(self) -> None:
133+
dsl_path = resource("dsl/custom_workflow_mapping.yaml")
134+
deployment, _ = self.deploy_application(dsl_path)
135+
deployment_id = deployment.id
136+
137+
deployment = self.client.deployments.get(deployment_id)
138+
deployment_updates = self.client.deployment_updates.list(
139+
deployment_id=deployment_id, _include=['id', 'steps']
140+
)
141+
142+
for step in deployment_updates.items[0].steps:
143+
assert 'id' in step
144+
145+
assert 'action' in step and step['action'] is not None
146+
assert 'entity_id' in step and step['entity_id'] is not None
147+
assert 'entity_type' in step and step['entity_type'] is not None
148+
assert 'topology_order' in step and step['topology_order'] is not None
149+
assert 'private_resource' in step and step['private_resource'] is not None
150+
assert 'visibility' in step and step['visibility'] is not None

0 commit comments

Comments
 (0)