Repository: readthedocs/readthedocs.org
Issue: External builds don't use the same builder as normal builds (defaullt vs large)

## Details

* Read the Docs project URL: https://readthedocs.org/projects/poliastro/
* Build URL (if applicable): https://readthedocs.org/projects/poliastro/builds/12722868/
* Read the Docs username (if applicable): Juanlu001

## Expected Result

If my pull request succeeds:

https://github.com/poliastro/poliastro/pull/1069, https://readthedocs.org/projects/poliastro/builds/12722362/

I'd expect the build to succeeds after merging to `master`.

## Actual Result

`master` is consistently failing. Last build: https://readthedocs.org/projects/poliastro/builds/12722868/

---

At the beginning, we suspected of a particular notebook that might take too much time or RAM to render. However, we did not observe long running times or excessive RAM usage locally. Then, the PR builder succeeded to render that notebook just fine. `latest` builds have been failing for a while now, and we don't know what else to do to debug the issue.

Changed files:
readthedocs/builds/tests/test_celery_task_router.py, readthedocs/builds/tasks.py

diff --git a/readthedocs/builds/tasks.py b/readthedocs/builds/tasks.py
index 4534a580b..d06265b84 100644
--- a/readthedocs/builds/tasks.py
+++ b/readthedocs/builds/tasks.py
@@ -15,6 +15,7 @@ from readthedocs.api.v2.utils import (
 )
 from readthedocs.builds.constants import (
     BRANCH,
+    EXTERNAL,
     BUILD_STATUS_FAILURE,
     BUILD_STATUS_PENDING,
     BUILD_STATUS_SUCCESS,
@@ -38,10 +39,11 @@ class TaskRouter:
     Celery tasks router.
 
     It allows us to decide which queue is where we want to execute the task
-    based on project's settings but also in queue availability.
+    based on project's settings.
 
     1. the project is using conda
     2. new project with less than N successful builds
+    3. version to be built is external
 
     It ignores projects that have already set ``build_queue`` attribute.
 
@@ -92,6 +94,16 @@ class TaskRouter:
                 )
                 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(
diff --git a/readthedocs/builds/tests/test_celery_task_router.py b/readthedocs/builds/tests/test_celery_task_router.py
index b1077eba5..713715038 100644
--- a/readthedocs/builds/tests/test_celery_task_router.py
+++ b/readthedocs/builds/tests/test_celery_task_router.py
@@ -3,6 +3,7 @@ from django.conf import settings
 from django.test import TestCase
 from django.test.utils import override_settings
 
+from readthedocs.builds.constants import EXTERNAL
 from readthedocs.builds.models import Build, Version
 from readthedocs.builds.tasks import TaskRouter
 from readthedocs.projects.models import Project
@@ -67,3 +68,23 @@ class TaskRouterTests(TestCase):
         self.assertIsNone(
             self.router.route_for_task(self.task, self.args, {}),
         )
+
+    def test_external_version(self):
+        self.version.type = EXTERNAL
+        self.version.save()
+
+        self.build.builder = 'build-default-a1b2c3'
+        self.build.save()
+
+        self.assertEqual(
+            self.router.route_for_task(self.task, self.args, self.kwargs),
+            TaskRouter.BUILD_DEFAULT_QUEUE,
+        )
+
+        self.build.builder = 'build-large-a1b2c3'
+        self.build.save()
+
+        self.assertEqual(
+            self.router.route_for_task(self.task, self.args, self.kwargs),
+            TaskRouter.BUILD_LARGE_QUEUE,
+        )