Skip to content
Snippets Groups Projects
Commit 104d10a1 authored by Erwan Rouchet's avatar Erwan Rouchet Committed by Bastien Abadie
Browse files

Optimize Revision.state and ListWorkerVersions

parent bd12a522
No related branches found
No related tags found
1 merge request!1038Optimize Revision.state and ListWorkerVersions
......@@ -694,9 +694,11 @@ class WorkerVersionList(ListCreateAPIView):
}
def get_queryset(self):
return WorkerVersion.objects.filter(
worker_id=self.kwargs['pk']
).prefetch_related('revision').order_by('-revision__created')
return WorkerVersion.objects \
.filter(worker_id=self.kwargs['pk']) \
.select_related('revision__repo', 'worker__repository') \
.prefetch_related('revision__refs', 'revision__versions') \
.order_by('-revision__created')
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
......
......@@ -352,13 +352,24 @@ class Revision(IndexableModel):
@property
def state(self):
# Computes revision state according to its versions one
"""
Computes revision state according to its versions'
# If there is one version in error, revision state is too
# Else if there is one version processing, revision state is too
# Else if all versions are available, then the revision is too
# Else, the revision is created since it has either no version or versions mixing processing/created states
states = set(self.versions.values_list('state', flat=True))
If there is one version in error, revision state is too
Else if there is one version processing, revision state is too
Else if all versions are available, then the revision is too
Else, the revision is created since it has either no version or versions mixing processing/created states
"""
# This prevents performing another SQL request when versions have already been prefetched.
# See https://stackoverflow.com/a/19651840/5990435
if (
hasattr(self, "_prefetched_objects_cache")
and self.versions.field.remote_field.get_cache_name()
in self._prefetched_objects_cache
):
states = set(version.state for version in self.versions.all())
else:
states = set(self.versions.values_list('state', flat=True))
if WorkerVersionState.Error in states:
return WorkerVersionState.Error
......
......@@ -46,6 +46,11 @@ class WorkerVersionSerializer(serializers.ModelSerializer):
'worker',
)
read_only_fields = ('docker_image_name',)
# Avoid loading all revisions and all Ponos artifacts when opening this endpoint in a browser
extra_kwargs = {
'revision': {'style': {'base_template': 'input.html'}},
'docker_image': {'style': {'base_template': 'input.html'}},
}
def to_representation(self, instance):
self.fields['revision'] = RevisionWithRefsSerializer(read_only=True)
......
......@@ -162,12 +162,14 @@ class TestWorkersWorkerVersions(FixtureAPITestCase):
# Tests on get_query_set for WorkerVersionList
def test_versions_list_requires_login(self):
response = self.client.get(reverse('api:worker-versions', kwargs={'pk': str(self.worker_1.id)}))
with self.assertNumQueries(0):
response = self.client.get(reverse('api:worker-versions', kwargs={'pk': str(self.worker_1.id)}))
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
def test_versions_list(self):
self.client.force_login(self.user)
response = self.client.get(reverse('api:worker-versions', kwargs={'pk': str(self.worker_1.id)}))
with self.assertNumQueries(5):
response = self.client.get(reverse('api:worker-versions', kwargs={'pk': str(self.worker_1.id)}))
self.assertEqual(response.status_code, status.HTTP_200_OK)
data = response.json()
self.assertEqual(len(data), 1)
......@@ -190,7 +192,8 @@ class TestWorkersWorkerVersions(FixtureAPITestCase):
configuration={"test": "test2"}
)
response = self.client.get(reverse('api:worker-versions', kwargs={'pk': str(worker_2.id)}))
with self.assertNumQueries(5):
response = self.client.get(reverse('api:worker-versions', kwargs={'pk': str(worker_2.id)}))
self.assertEqual(response.status_code, status.HTTP_200_OK)
data = response.json()
self.assertEqual(len(data), 1)
......
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