Skip to content

Commit f1381b0

Browse files
committed
refactor: separated queue views to several files
1 parent 3256a08 commit f1381b0

File tree

14 files changed

+94
-111
lines changed

14 files changed

+94
-111
lines changed

scheduler/helpers/queues/getters.py

-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
from .queue_logic import Queue
1313

1414

15-
1615
_BAD_QUEUE_CONFIGURATION = set()
1716

1817

@@ -77,5 +76,3 @@ def get_all_workers() -> Set[WorkerModel]:
7776
logger.error(f"Could not connect for queue {queue_name}: {e}")
7877
_BAD_QUEUE_CONFIGURATION.add(queue_name)
7978
return workers_set
80-
81-

scheduler/management/commands/scheduler_stats.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def add_arguments(self, parser):
5050
def _print_separator(self):
5151
click.echo("-" * self.table_width)
5252

53-
def _print_stats_dashboard(self, statistics, prev_stats=None, with_color:bool = True):
53+
def _print_stats_dashboard(self, statistics, prev_stats=None, with_color: bool = True):
5454
if self.interval:
5555
click.clear()
5656
click.echo()

scheduler/templates/admin/scheduler/job_detail.html

+4-4
Original file line numberDiff line numberDiff line change
@@ -149,27 +149,27 @@ <h2 class="fieldset-heading">Last result</h2>
149149
</fieldset>
150150
<div class="submit-row">
151151
<div class="deletelink-box">
152-
<a href="{% url 'queue_job_action' job.name 'delete' %}" class="deletelink">Delete</a>
152+
<a href="{% url 'job_detail_action' job.name 'delete' %}" class="deletelink">Delete</a>
153153
</div>
154154
{% if job.is_started %}
155155
<div class="deletelink-box">
156-
<form method='POST' action="{% url 'queue_job_action' job.name 'cancel' %}">
156+
<form method='POST' action="{% url 'job_detail_action' job.name 'cancel' %}">
157157
{% csrf_token %}
158158
<input type="submit" value="cancel" class="default" name="cancel">
159159
</form>
160160
</div>
161161
{% endif %}
162162
{% if job.is_failed %}
163163
<div class="deletelink-box">
164-
<form method='POST' action="{% url 'queue_job_action' job.name 'requeue' %}">
164+
<form method='POST' action="{% url 'job_detail_action' job.name 'requeue' %}">
165165
{% csrf_token %}
166166
<input type="submit" value="Requeue" class="default" name="requeue">
167167
</form>
168168
</div>
169169
{% endif %}
170170
{% if not job.is_queued and not job.is_failed %}
171171
<div class="deletelink-box">
172-
<form method='POST' action="{% url 'queue_job_action' job.name 'enqueue' %}">
172+
<form method='POST' action="{% url 'job_detail_action' job.name 'enqueue' %}">
173173
{% csrf_token %}
174174
<input type="submit" value="Enqueue" class="default" name="Requeue">
175175
</form>

scheduler/templates/admin/scheduler/jobs.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
<li><a href="{% url 'queue_registry_action' queue.name registry_name 'empty' %}" class="deletelink">Empty Queue</a></li>
3232
</ul>
3333
<div class="module" id="changelist">
34-
<form id="changelist-form" action="{% url 'queue_confirm_action' queue.name %}" method="post">
34+
<form id="changelist-form" action="{% url 'queue_confirm_job_action' queue.name %}" method="post">
3535
{% csrf_token %}
3636
<div class="actions">
3737
<label>Actions:

scheduler/tests/test_multiprocess/test_integrity.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def test_cancel_job_after_it_started(self):
2222
job = JobModel.get(job.name, connection=queue.connection)
2323
self.assertEqual(JobStatus.STARTED, job.status)
2424
# act
25-
res = self.client.post(reverse("queue_job_action", args=[job.name, "cancel"]), {"post": "yes"}, follow=True)
25+
res = self.client.post(reverse("job_detail_action", args=[job.name, "cancel"]), {"post": "yes"}, follow=True)
2626

2727
# assert
2828
self.assertEqual(200, res.status_code)

scheduler/tests/test_task_types/test_task_model.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ def test_admin_change_view__bad_redis_connection(self):
340340
# arrange
341341
self.client.login(username="admin", password="admin")
342342
task = task_factory(self.task_type, queue="test2", instance_only=True)
343-
task.save(schedule_job=False)
343+
task.save(schedule_job=False)
344344
url = reverse(
345345
f"admin:scheduler_task_change",
346346
args=[

scheduler/tests/test_views/test_queue_job_action.py renamed to scheduler/tests/test_views/test_job_detail_action.py

+14-14
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
class SingleJobActionViewsTest(BaseTestCase):
1313
def test_single_job_action_unknown_job(self):
14-
res = self.client.get(reverse("queue_job_action", args=["unknown", "cancel"]), follow=True)
14+
res = self.client.get(reverse("job_detail_action", args=["unknown", "cancel"]), follow=True)
1515
self.assertEqual(200, res.status_code)
1616
assert_response_has_msg(res, "Job unknown does not exist, maybe its TTL has passed")
1717

@@ -22,7 +22,7 @@ def test_single_job_action_unknown_action(self):
2222
worker.work()
2323
job = JobModel.get(job.name, connection=queue.connection)
2424
self.assertTrue(job.is_failed)
25-
res = self.client.get(reverse("queue_job_action", args=[job.name, "unknown"]), follow=True)
25+
res = self.client.get(reverse("job_detail_action", args=[job.name, "unknown"]), follow=True)
2626
self.assertEqual(400, res.status_code)
2727

2828
def test_single_job_action_requeue_job(self):
@@ -32,18 +32,18 @@ def test_single_job_action_requeue_job(self):
3232
worker.work()
3333
job = JobModel.get(job.name, connection=queue.connection)
3434
self.assertTrue(job.is_failed)
35-
res = self.client.get(reverse("queue_job_action", args=[job.name, "requeue"]), follow=True)
35+
res = self.client.get(reverse("job_detail_action", args=[job.name, "requeue"]), follow=True)
3636
self.assertEqual(200, res.status_code)
37-
self.client.post(reverse("queue_job_action", args=[job.name, "requeue"]), {"requeue": "Requeue"}, follow=True)
37+
self.client.post(reverse("job_detail_action", args=[job.name, "requeue"]), {"requeue": "Requeue"}, follow=True)
3838
self.assertIn(job, JobModel.get_many(queue.queued_job_registry.all(), queue.connection))
3939
queue.delete_job(job.name)
4040

4141
def test_single_job_action_delete_job(self):
4242
queue = get_queue("default")
4343
job = queue.create_and_enqueue_job(test_job, job_info_ttl=0)
44-
res = self.client.get(reverse("queue_job_action", args=[job.name, "delete"]), follow=True)
44+
res = self.client.get(reverse("job_detail_action", args=[job.name, "delete"]), follow=True)
4545
self.assertEqual(200, res.status_code)
46-
self.client.post(reverse("queue_job_action", args=[job.name, "delete"]), {"post": "yes"}, follow=True)
46+
self.client.post(reverse("job_detail_action", args=[job.name, "delete"]), {"post": "yes"}, follow=True)
4747
self.assertFalse(JobModel.exists(job.name, connection=queue.connection))
4848
self.assertNotIn(job.name, queue.queued_job_registry.all())
4949

@@ -52,9 +52,9 @@ def test_single_job_action_cancel_job(self):
5252
job = queue.create_and_enqueue_job(long_job)
5353
self.assertTrue(job.is_queued)
5454
job = JobModel.get(job.name, connection=queue.connection)
55-
res = self.client.get(reverse("queue_job_action", args=[job.name, "cancel"]), follow=True)
55+
res = self.client.get(reverse("job_detail_action", args=[job.name, "cancel"]), follow=True)
5656
self.assertEqual(200, res.status_code)
57-
res = self.client.post(reverse("queue_job_action", args=[job.name, "cancel"]), {"post": "yes"}, follow=True)
57+
res = self.client.post(reverse("job_detail_action", args=[job.name, "cancel"]), {"post": "yes"}, follow=True)
5858
self.assertEqual(200, res.status_code)
5959
job = JobModel.get(job.name, connection=queue.connection)
6060
self.assertTrue(job.is_canceled)
@@ -63,12 +63,12 @@ def test_single_job_action_cancel_job(self):
6363
def test_single_job_action_cancel_job_that_is_already_cancelled(self):
6464
queue = get_queue("django_tasks_scheduler_test")
6565
job = queue.create_and_enqueue_job(long_job)
66-
res = self.client.post(reverse("queue_job_action", args=[job.name, "cancel"]), {"post": "yes"}, follow=True)
66+
res = self.client.post(reverse("job_detail_action", args=[job.name, "cancel"]), {"post": "yes"}, follow=True)
6767
self.assertEqual(200, res.status_code)
6868
tmp = JobModel.get(job.name, connection=queue.connection)
6969
self.assertTrue(tmp.is_canceled)
7070
self.assertNotIn(job.name, queue.queued_job_registry.all())
71-
res = self.client.post(reverse("queue_job_action", args=[job.name, "cancel"]), {"post": "yes"}, follow=True)
71+
res = self.client.post(reverse("job_detail_action", args=[job.name, "cancel"]), {"post": "yes"}, follow=True)
7272
self.assertEqual(200, res.status_code)
7373
assert_message_in_response(res, f"Could not perform action: Cannot cancel already canceled job: {job.name}")
7474

@@ -86,9 +86,9 @@ def test_single_job_action_enqueue_job(self):
8686
self.assertIsNotNone(job_list[-1].enqueued_at)
8787

8888
# Try to force enqueue last job should do nothing
89-
res = self.client.get(reverse("queue_job_action", args=[job_list[-1].name, "enqueue"]), follow=True)
89+
res = self.client.get(reverse("job_detail_action", args=[job_list[-1].name, "enqueue"]), follow=True)
9090
self.assertEqual(200, res.status_code)
91-
res = self.client.post(reverse("queue_job_action", args=[job_list[-1].name, "enqueue"]), follow=True)
91+
res = self.client.post(reverse("job_detail_action", args=[job_list[-1].name, "enqueue"]), follow=True)
9292

9393
self.assertEqual(200, res.status_code)
9494
tmp = JobModel.get(job_list[-1].name, connection=queue.connection)
@@ -109,9 +109,9 @@ def test_single_job_action_enqueue_job_sync_queue(self):
109109
self.assertIsNotNone(job_list[-1].enqueued_at)
110110

111111
# Try to force enqueue last job should do nothing
112-
res = self.client.get(reverse("queue_job_action", args=[job_list[-1].name, "enqueue"]), follow=True)
112+
res = self.client.get(reverse("job_detail_action", args=[job_list[-1].name, "enqueue"]), follow=True)
113113
self.assertEqual(200, res.status_code)
114-
res = self.client.post(reverse("queue_job_action", args=[job_list[-1].name, "enqueue"]), follow=True)
114+
res = self.client.post(reverse("job_detail_action", args=[job_list[-1].name, "enqueue"]), follow=True)
115115

116116
self.assertEqual(200, res.status_code)
117117
tmp = JobModel.get(job_list[-1].name, connection=queue.connection)

scheduler/tests/test_views/test_job_details.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,9 @@ def test_clear_queue_scheduled(self):
114114
self.assertEqual(200, res.status_code)
115115
self.assertEqual(res.context["jobs"], [job])
116116

117-
res = self.client.post(reverse("queue_registry_action", args=[queue.name, "scheduled", "empty"]),
118-
{"post": "yes"}, follow=True)
117+
res = self.client.post(
118+
reverse("queue_registry_action", args=[queue.name, "scheduled", "empty"]), {"post": "yes"}, follow=True
119+
)
119120
assert_message_in_response(res, f"You have successfully cleared the scheduled jobs in queue {queue.name}")
120121
self.assertEqual(200, res.status_code)
121122
self.assertFalse(JobModel.exists(job.name, connection=queue.connection))

scheduler/tests/test_views/test_queue_actions.py

+5-15
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
from django.urls import reverse
22

33
from scheduler.helpers.queues import get_queue
4-
from scheduler.worker import create_worker
54
from scheduler.redis_models import JobStatus, JobModel
65
from scheduler.tests.jobs import failing_job, test_job
76
from scheduler.tests.test_views.base import BaseTestCase
87
from scheduler.tests.testtools import assert_message_in_response
8+
from scheduler.worker import create_worker
99

1010

1111
class QueueActionsViewsTest(BaseTestCase):
@@ -20,12 +20,7 @@ def test_job_list_action_delete_jobs__with_bad_next_url(self):
2020

2121
# remove those jobs using view
2222
res = self.client.post(
23-
reverse(
24-
"queue_actions",
25-
args=[
26-
queue.name,
27-
],
28-
),
23+
reverse("queue_job_actions", args=[queue.name]),
2924
{
3025
"action": "delete",
3126
"job_names": job_names,
@@ -51,12 +46,7 @@ def test_job_list_action_delete_jobs(self):
5146

5247
# remove those jobs using view
5348
res = self.client.post(
54-
reverse(
55-
"queue_actions",
56-
args=[
57-
queue.name,
58-
],
59-
),
49+
reverse("queue_job_actions", args=[queue.name]),
6050
{"action": "delete", "job_names": job_names},
6151
follow=True,
6252
)
@@ -87,7 +77,7 @@ def test_job_list_action_requeue_jobs(self):
8777
self.assertTrue(job.is_failed)
8878

8979
# re-nqueue failed jobs from failed queue
90-
self.client.post(reverse("queue_actions", args=[queue_name]), {"action": "requeue", "job_names": job_names})
80+
self.client.post(reverse("queue_job_actions", args=[queue_name]), {"action": "requeue", "job_names": job_names})
9181

9282
# check if we requeue all failed jobs
9383
for job_name in job_names:
@@ -115,7 +105,7 @@ def test_job_list_action_stop_jobs__move_to_finished_registry(self):
115105

116106
# Stop those jobs using the view
117107
self.assertEqual(len(queue.active_job_registry), len(job_names))
118-
self.client.post(reverse("queue_actions", args=[queue_name]), {"action": "stop", "job_names": job_names})
108+
self.client.post(reverse("queue_job_actions", args=[queue_name]), {"action": "stop", "job_names": job_names})
119109
self.assertEqual(0, len(queue.active_job_registry))
120110

121111
self.assertEqual(0, len(queue.canceled_job_registry))

scheduler/urls.py

+8-4
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,18 @@
77
path("queues/stats.json", views.stats_json, name="queues_home_json"),
88
path("queues/<str:queue_name>/workers/", views.queue_workers, name="queue_workers"),
99
path("queues/<str:queue_name>/<str:registry_name>/jobs", views.list_registry_jobs, name="queue_registry_jobs"),
10-
path("queues/<str:queue_name>/<str:registry_name>/<str:action>/", views.queue_registry_actions, name="queue_registry_action"),
11-
path("queues/<str:queue_name>/confirm-action/", views.queue_confirm_action, name="queue_confirm_action"),
12-
path("queues/<str:queue_name>/actions/", views.queue_job_actions, name="queue_actions"),
10+
path(
11+
"queues/<str:queue_name>/<str:registry_name>/<str:action>/",
12+
views.queue_registry_actions,
13+
name="queue_registry_action",
14+
),
15+
path("queues/<str:queue_name>/confirm-action/", views.queue_confirm_job_action, name="queue_confirm_job_action"),
16+
path("queues/<str:queue_name>/actions/", views.queue_job_actions, name="queue_job_actions"),
1317
]
1418

1519
urlpatterns += [
1620
path("workers/", views.workers_list, name="workers_home"),
1721
path("workers/<str:name>/", views.worker_details, name="worker_details"),
1822
path("jobs/<str:job_name>/", views.job_detail, name="job_details"),
19-
path("jobs/<str:job_name>/<str:action>/", views.job_action, name="queue_job_action"),
23+
path("jobs/<str:job_name>/<str:action>/", views.job_action, name="job_detail_action"),
2024
]

scheduler/views/__init__.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"stats",
55
"stats_json",
66
"queue_registry_actions",
7-
"queue_confirm_action",
7+
"queue_confirm_job_action",
88
"queue_workers",
99
"queue_job_actions",
1010
"list_registry_jobs",
@@ -14,8 +14,8 @@
1414
]
1515

1616
from .job_views import job_detail, job_action
17-
from .queue_job_actions import queue_job_actions
18-
from .queue_registry_actions import queue_registry_actions, queue_confirm_action
17+
from .queue_job_actions import queue_job_actions, queue_confirm_job_action
18+
from .queue_registry_actions import queue_registry_actions
1919
from .queue_views import (
2020
stats,
2121
stats_json,

scheduler/views/queue_job_actions.py

+32-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1+
"""list_registry_jobs actions on multiple selected jobs"""
12
from enum import Enum
23

3-
from django.contrib import messages
4+
from django.contrib import admin, messages
45
from django.contrib.admin.views.decorators import staff_member_required
56
from django.http import HttpResponse, HttpRequest
6-
from django.shortcuts import redirect
7+
from django.shortcuts import render, redirect
78
from django.urls import reverse
89
from django.views.decorators.cache import never_cache
910

@@ -26,11 +27,9 @@ def queue_job_actions(request: HttpRequest, queue_name: str) -> HttpResponse:
2627
next_url = _check_next_url(request, reverse("queue_registry_jobs", args=[queue_name, "queued"]))
2728
action = request.POST.get("action", False)
2829
job_names = request.POST.get("job_names", False)
29-
if request.method != "POST" or not action or not job_names:
30+
if request.method != "POST" or not action or not job_names or action not in QueueJobAction:
3031
return redirect(next_url)
3132
job_names = request.POST.getlist("job_names")
32-
if action not in QueueJobAction:
33-
return redirect(next_url)
3433
if action == QueueJobAction.DELETE:
3534
jobs = JobModel.get_many(job_names, connection=queue.connection)
3635
for job in jobs:
@@ -57,3 +56,31 @@ def queue_job_actions(request: HttpRequest, queue_name: str) -> HttpResponse:
5756
pass
5857
messages.info(request, f"You have successfully stopped {cancelled_jobs} jobs!")
5958
return redirect(next_url)
59+
60+
61+
@never_cache
62+
@staff_member_required
63+
def queue_confirm_job_action(request: HttpRequest, queue_name: str) -> HttpResponse:
64+
queue = get_queue(queue_name)
65+
next_url = _check_next_url(request, reverse("queue_registry_jobs", args=[queue_name, "queued"]))
66+
action = request.POST.get("action", None)
67+
job_names = request.POST.getlist("_selected_action", None)
68+
if request.method != "POST" or action is None or job_names is None or action not in QueueJobAction:
69+
return redirect(next_url)
70+
71+
# confirm action
72+
context_data = {
73+
**admin.site.each_context(request),
74+
"action": action,
75+
"jobs": [JobModel.get(job_name, connection=queue.connection) for job_name in job_names],
76+
"total_jobs": len(job_names),
77+
"queue": queue,
78+
"next_url": next_url,
79+
"action_url": reverse(
80+
"queue_job_actions",
81+
args=[
82+
queue_name,
83+
],
84+
),
85+
}
86+
return render(request, "admin/scheduler/confirm_action.html", context_data)

scheduler/views/queue_registry_actions.py

+2-38
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"""list_registry_jobs actions on all jobs in the registry"""
12
from enum import Enum
23

34
from django.contrib import admin, messages
@@ -66,43 +67,6 @@ def queue_registry_actions(request: HttpRequest, queue_name: str, registry_name:
6667
"action": action,
6768
"jobs": job_list,
6869
"next_url": next_url,
69-
"action_url": reverse(
70-
"queue_registry_action",
71-
args=[
72-
queue_name,
73-
registry_name,
74-
action
75-
],
76-
),
77-
}
78-
return render(request, "admin/scheduler/confirm_action.html", context_data)
79-
80-
81-
@never_cache
82-
@staff_member_required
83-
def queue_confirm_action(request: HttpRequest, queue_name: str) -> HttpResponse:
84-
queue = get_queue(queue_name)
85-
next_url = _check_next_url(request, reverse("queue_registry_jobs", args=[queue_name, "queued"]))
86-
if request.method != "POST":
87-
return redirect(next_url)
88-
action = request.POST.get("action", None)
89-
job_names = request.POST.getlist("_selected_action", None)
90-
if action is None or job_names is None:
91-
return redirect(next_url)
92-
93-
# confirm action
94-
context_data = {
95-
**admin.site.each_context(request),
96-
"action": action,
97-
"jobs": [JobModel.get(job_name, connection=queue.connection) for job_name in job_names],
98-
"total_jobs": len(job_names),
99-
"queue": queue,
100-
"next_url": next_url,
101-
"action_url": reverse(
102-
"queue_actions",
103-
args=[
104-
queue_name,
105-
],
106-
),
70+
"action_url": reverse("queue_registry_action", args=[queue_name, registry_name, action]),
10771
}
10872
return render(request, "admin/scheduler/confirm_action.html", context_data)

0 commit comments

Comments
 (0)