Skip to content

Commit

Permalink
Build: allow to cancel a queued build that hasn't started yet
Browse files Browse the repository at this point in the history
  • Loading branch information
humitos committed Feb 22, 2022
1 parent c0a951a commit 5066e64
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
class Migration(migrations.Migration):

dependencies = [
('builds', '0037_alter_build_cold_storage'),
('builds', '0040_remove_old_jsonfields.py'),
]

operations = [
Expand Down
28 changes: 20 additions & 8 deletions readthedocs/builds/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,14 @@
from django.views.generic import DetailView, ListView
from requests.utils import quote

from readthedocs.builds.constants import BUILD_STATE_TRIGGERED, BUILD_STATE_FINISHED
from readthedocs.builds.filters import BuildListFilter
from readthedocs.builds.models import Build, Version
from readthedocs.core.permissions import AdminPermission
from readthedocs.core.utils import trigger_build
from readthedocs.doc_builder.exceptions import BuildAppError
from readthedocs.doc_builder.exceptions import BuildAppError, BuildCancelled
from readthedocs.projects.models import Project

try:
from readthedocsinc.worker import app
except ImportError:
from readthedocs.worker import app
from readthedocs.worker import app


log = structlog.get_logger(__name__)
Expand Down Expand Up @@ -165,8 +162,23 @@ def post(self, request, project_slug, build_pk):
return HttpResponseForbidden()

# NOTE: `terminate=True` is required for the child to attend our call
# immediately. Otherwise, it finishes the task.
app.control.revoke(build.task_id, signal=signal.SIGINT, terminate=True)
# immediately when it's running the build. Otherwise, it finishes the
# task. However, to revoke a task that has not started yet, we don't
# need it.
if build.state == BUILD_STATE_TRIGGERED:
# Since the task won't be executed at all, we need to update the
# Build object here.
terminate = False
build.state = BUILD_STATE_FINISHED
build.success = False
build.error = BuildCancelled.message
build.save()
else:
# In this case, we left the update of the Build object to the task
# itself to be executed in the `on_failure` handler.
terminate = True

app.control.revoke(build.task_id, signal=signal.SIGINT, terminate=terminate)

return HttpResponseRedirect(
reverse('builds_detail', args=[project.slug, build.pk]),
Expand Down
2 changes: 2 additions & 0 deletions readthedocs/templates/builds/build_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,12 @@
{% block content %}
<div class="build build-detail" id="build-detail">

{% if build.state != "finished" %}
<form method="post" action="{% url "builds_detail" build.version.project.slug build.pk %}">
{% csrf_token %}
<input type="submit" value="{% trans "Cancel build" %}">
</form>
{% endif %}

<!-- Build meta data -->
<ul class="build-meta">
Expand Down

0 comments on commit 5066e64

Please sign in to comment.