Skip to content

Route external versions to the queue were default version was built #7933

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 18 additions & 10 deletions readthedocs/builds/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,24 @@ def route_for_task(self, task, args, kwargs, **__):
)
return project.build_queue

# Use last queue used by the default version for external versions
if version.type == EXTERNAL:
last_build_for_default_version = (
project.builds
.filter(version__slug=project.get_default_version())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should filter success=True here? Though I guess that isn't really a good check, and might miss ones without a successful build on the default project.

I wonder if what we really want is an attribute on the project that keeps track of what queue it should use? I don't know if there's a "correct" way of handling this for every case though.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if what we really want is an attribute on the project that keeps track of what queue it should use?

I thought about something like this as well but I wasn't sure it was a good idea. We could talk a little more about this and share our thoughts. I think this PR is fine for now, tho.

I don't know if there's a "correct" way of handling this for every case though.

Yeah, 😞

.order_by('-date')
.first()
)
if 'default' in last_build_for_default_version.builder:
routing_queue = self.BUILD_DEFAULT_QUEUE
else:
routing_queue = self.BUILD_LARGE_QUEUE
log.info(
'Routing task because is a external version. project=%s queue=%s',
project.slug, routing_queue,
)
return routing_queue

queryset = version.builds.filter(success=True).order_by('-date')
last_builds = queryset[:self.N_LAST_BUILDS]

Expand All @@ -94,16 +112,6 @@ def route_for_task(self, task, args, kwargs, **__):
)
return self.BUILD_LARGE_QUEUE

# Use last queue used for external versions
if version.type == EXTERNAL:
for build in last_builds.iterator():
if not build.builder:
continue

if 'default' in build.builder:
return self.BUILD_DEFAULT_QUEUE
return self.BUILD_LARGE_QUEUE

# We do not have enough builds for this version yet
if queryset.count() < self.N_BUILDS:
log.info(
Expand Down
28 changes: 19 additions & 9 deletions readthedocs/builds/tests/test_celery_task_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,21 +70,31 @@ def test_no_build_pk(self):
)

def test_external_version(self):
self.version.type = EXTERNAL
self.version.save()

self.build.builder = 'build-default-a1b2c3'
self.build.save()
external_version = fixture.get(
Version,
project=self.project,
slug='pull-request',
type=EXTERNAL,
)
default_version = self.project.versions.get(slug=self.project.get_default_version())
default_version_build = fixture.get(
Build,
version=default_version,
project=self.project,
builder='build-default-a1b2c3',
)
args = (external_version.pk,)
kwargs = {'build_pk': default_version_build.pk}

self.assertEqual(
self.router.route_for_task(self.task, self.args, self.kwargs),
self.router.route_for_task(self.task, args, kwargs),
TaskRouter.BUILD_DEFAULT_QUEUE,
)

self.build.builder = 'build-large-a1b2c3'
self.build.save()
default_version_build.builder = 'build-large-a1b2c3'
default_version_build.save()

self.assertEqual(
self.router.route_for_task(self.task, self.args, self.kwargs),
self.router.route_for_task(self.task, args, kwargs),
TaskRouter.BUILD_LARGE_QUEUE,
)