dj-queue 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dj_queue/__init__.py +0 -0
- dj_queue/admin.py +90 -0
- dj_queue/api.py +122 -0
- dj_queue/apps.py +6 -0
- dj_queue/backend.py +161 -0
- dj_queue/config.py +456 -0
- dj_queue/contrib/__init__.py +1 -0
- dj_queue/contrib/asgi.py +32 -0
- dj_queue/contrib/gunicorn.py +25 -0
- dj_queue/db.py +68 -0
- dj_queue/exceptions.py +26 -0
- dj_queue/hooks.py +86 -0
- dj_queue/log.py +27 -0
- dj_queue/management/__init__.py +1 -0
- dj_queue/management/commands/__init__.py +1 -0
- dj_queue/management/commands/dj_queue.py +39 -0
- dj_queue/management/commands/dj_queue_health.py +32 -0
- dj_queue/management/commands/dj_queue_prune.py +22 -0
- dj_queue/migrations/0001_initial.py +262 -0
- dj_queue/migrations/0002_pause_semaphore.py +52 -0
- dj_queue/migrations/0003_recurringtask_recurringexecution.py +73 -0
- dj_queue/migrations/__init__.py +0 -0
- dj_queue/models/__init__.py +24 -0
- dj_queue/models/jobs.py +328 -0
- dj_queue/models/recurring.py +51 -0
- dj_queue/models/runtime.py +55 -0
- dj_queue/operations/__init__.py +1 -0
- dj_queue/operations/cleanup.py +37 -0
- dj_queue/operations/concurrency.py +176 -0
- dj_queue/operations/jobs.py +637 -0
- dj_queue/operations/recurring.py +81 -0
- dj_queue/routers.py +26 -0
- dj_queue/runtime/__init__.py +1 -0
- dj_queue/runtime/base.py +198 -0
- dj_queue/runtime/dispatcher.py +78 -0
- dj_queue/runtime/errors.py +39 -0
- dj_queue/runtime/interruptible.py +46 -0
- dj_queue/runtime/notify.py +119 -0
- dj_queue/runtime/pidfile.py +39 -0
- dj_queue/runtime/pool.py +62 -0
- dj_queue/runtime/procline.py +11 -0
- dj_queue/runtime/scheduler.py +128 -0
- dj_queue/runtime/supervisor.py +460 -0
- dj_queue/runtime/worker.py +116 -0
- dj_queue-0.1.0.dist-info/METADATA +613 -0
- dj_queue-0.1.0.dist-info/RECORD +48 -0
- dj_queue-0.1.0.dist-info/WHEEL +4 -0
- dj_queue-0.1.0.dist-info/licenses/LICENSE +21 -0
dj_queue/log.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from dj_queue.config import load_backend_config
|
|
5
|
+
|
|
6
|
+
logger = logging.getLogger("dj_queue")
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def log_event(
|
|
10
|
+
event: str,
|
|
11
|
+
*,
|
|
12
|
+
level: int = logging.INFO,
|
|
13
|
+
backend_alias: str = "default",
|
|
14
|
+
polling: bool = False,
|
|
15
|
+
**fields: Any,
|
|
16
|
+
):
|
|
17
|
+
if polling and load_backend_config(backend_alias).silence_polling:
|
|
18
|
+
return
|
|
19
|
+
|
|
20
|
+
logger.log(
|
|
21
|
+
level,
|
|
22
|
+
event,
|
|
23
|
+
extra={
|
|
24
|
+
"event": event,
|
|
25
|
+
"dj_queue": fields,
|
|
26
|
+
},
|
|
27
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Management package for dj_queue."""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Management commands for dj_queue."""
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
from django.core.management.base import BaseCommand
|
|
2
|
+
|
|
3
|
+
from dj_queue.config import load_backend_config
|
|
4
|
+
from dj_queue.runtime.supervisor import AsyncSupervisor, ForkSupervisor
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def build_supervisor(*, backend_alias, cli_overrides):
|
|
8
|
+
mode = load_backend_config(backend_alias, cli_overrides=cli_overrides).mode
|
|
9
|
+
supervisor_class = AsyncSupervisor if mode == "async" else ForkSupervisor
|
|
10
|
+
return supervisor_class.from_backend_config(
|
|
11
|
+
backend_alias=backend_alias,
|
|
12
|
+
cli_overrides=cli_overrides,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class Command(BaseCommand):
|
|
17
|
+
help = "Start the dj_queue supervisor"
|
|
18
|
+
|
|
19
|
+
def add_arguments(self, parser):
|
|
20
|
+
parser.add_argument("--backend", default="default")
|
|
21
|
+
parser.add_argument("--config")
|
|
22
|
+
parser.add_argument("--mode", choices=("fork", "async"))
|
|
23
|
+
parser.add_argument("--only-work", action="store_true")
|
|
24
|
+
parser.add_argument("--only-dispatch", action="store_true")
|
|
25
|
+
parser.add_argument("--skip-recurring", action="store_true")
|
|
26
|
+
|
|
27
|
+
def handle(self, *args, **options):
|
|
28
|
+
cli_overrides = {
|
|
29
|
+
"config": options["config"],
|
|
30
|
+
"mode": options["mode"],
|
|
31
|
+
"only_work": options["only_work"],
|
|
32
|
+
"only_dispatch": options["only_dispatch"],
|
|
33
|
+
"skip_recurring": options["skip_recurring"],
|
|
34
|
+
}
|
|
35
|
+
supervisor = build_supervisor(
|
|
36
|
+
backend_alias=options["backend"],
|
|
37
|
+
cli_overrides=cli_overrides,
|
|
38
|
+
)
|
|
39
|
+
supervisor.run()
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from datetime import timedelta
|
|
2
|
+
|
|
3
|
+
from django.core.management.base import BaseCommand
|
|
4
|
+
from django.utils import timezone
|
|
5
|
+
|
|
6
|
+
from dj_queue.config import load_backend_config
|
|
7
|
+
from dj_queue.db import get_database_alias
|
|
8
|
+
from dj_queue.models import Process
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Command(BaseCommand):
|
|
12
|
+
help = "Check dj_queue process health"
|
|
13
|
+
|
|
14
|
+
def add_arguments(self, parser):
|
|
15
|
+
parser.add_argument("--backend", default="default")
|
|
16
|
+
parser.add_argument("--max-age", type=int)
|
|
17
|
+
|
|
18
|
+
def handle(self, *args, **options):
|
|
19
|
+
backend_alias = options["backend"]
|
|
20
|
+
config = load_backend_config(backend_alias)
|
|
21
|
+
max_age = options["max_age"]
|
|
22
|
+
if max_age is None:
|
|
23
|
+
max_age = config.process_alive_threshold
|
|
24
|
+
|
|
25
|
+
cutoff = timezone.now() - timedelta(seconds=max_age)
|
|
26
|
+
alias = get_database_alias(backend_alias)
|
|
27
|
+
healthy = Process.objects.using(alias).filter(last_heartbeat_at__gte=cutoff).exists()
|
|
28
|
+
if healthy:
|
|
29
|
+
self.stdout.write("healthy")
|
|
30
|
+
return
|
|
31
|
+
|
|
32
|
+
raise SystemExit(1)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from django.core.management.base import BaseCommand
|
|
2
|
+
|
|
3
|
+
from dj_queue.operations.cleanup import clear_finished_jobs
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Command(BaseCommand):
|
|
7
|
+
help = "Prune finished dj_queue jobs"
|
|
8
|
+
|
|
9
|
+
def add_arguments(self, parser):
|
|
10
|
+
parser.add_argument("--backend", default="default")
|
|
11
|
+
parser.add_argument("--older-than", type=int)
|
|
12
|
+
parser.add_argument("--batch-size", type=int, default=500)
|
|
13
|
+
parser.add_argument("--task-path")
|
|
14
|
+
|
|
15
|
+
def handle(self, *args, **options):
|
|
16
|
+
deleted = clear_finished_jobs(
|
|
17
|
+
older_than=options["older_than"],
|
|
18
|
+
task_path=options["task_path"],
|
|
19
|
+
batch_size=options["batch_size"],
|
|
20
|
+
backend_alias=options["backend"],
|
|
21
|
+
)
|
|
22
|
+
self.stdout.write(f"deleted {deleted} finished jobs")
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
# Generated by Django 6.0.3 on 2026-04-06 15:03
|
|
2
|
+
|
|
3
|
+
import django.db.models.deletion
|
|
4
|
+
import uuid
|
|
5
|
+
from django.db import migrations, models
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Migration(migrations.Migration):
|
|
9
|
+
initial = True
|
|
10
|
+
|
|
11
|
+
dependencies = []
|
|
12
|
+
|
|
13
|
+
operations = [
|
|
14
|
+
migrations.CreateModel(
|
|
15
|
+
name="Job",
|
|
16
|
+
fields=[
|
|
17
|
+
(
|
|
18
|
+
"id",
|
|
19
|
+
models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False),
|
|
20
|
+
),
|
|
21
|
+
("task_path", models.TextField()),
|
|
22
|
+
("queue_name", models.CharField(default="default", max_length=64)),
|
|
23
|
+
("priority", models.SmallIntegerField(default=0)),
|
|
24
|
+
("payload", models.JSONField(default=dict)),
|
|
25
|
+
("backend_name", models.CharField(max_length=64)),
|
|
26
|
+
("scheduled_at", models.DateTimeField(blank=True, null=True)),
|
|
27
|
+
("concurrency_key", models.CharField(blank=True, max_length=255, null=True)),
|
|
28
|
+
("finished_at", models.DateTimeField(blank=True, null=True)),
|
|
29
|
+
("return_value", models.JSONField(blank=True, null=True)),
|
|
30
|
+
("created_at", models.DateTimeField(auto_now_add=True)),
|
|
31
|
+
("updated_at", models.DateTimeField(auto_now=True)),
|
|
32
|
+
],
|
|
33
|
+
options={
|
|
34
|
+
"db_table": "dj_queue_jobs",
|
|
35
|
+
"indexes": [
|
|
36
|
+
models.Index(
|
|
37
|
+
fields=["queue_name", "finished_at"], name="dj_queue_jo_queue_n_b824ac_idx"
|
|
38
|
+
),
|
|
39
|
+
models.Index(
|
|
40
|
+
fields=["scheduled_at", "finished_at"], name="dj_queue_jo_schedul_92b51a_idx"
|
|
41
|
+
),
|
|
42
|
+
models.Index(fields=["finished_at"], name="dj_queue_jo_finishe_9acb9a_idx"),
|
|
43
|
+
],
|
|
44
|
+
"constraints": [
|
|
45
|
+
models.CheckConstraint(
|
|
46
|
+
condition=models.Q(("priority__gte", -100), ("priority__lte", 100)),
|
|
47
|
+
name="dj_queue_jobs_priority_range",
|
|
48
|
+
)
|
|
49
|
+
],
|
|
50
|
+
},
|
|
51
|
+
),
|
|
52
|
+
migrations.CreateModel(
|
|
53
|
+
name="FailedExecution",
|
|
54
|
+
fields=[
|
|
55
|
+
(
|
|
56
|
+
"id",
|
|
57
|
+
models.BigAutoField(
|
|
58
|
+
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
59
|
+
),
|
|
60
|
+
),
|
|
61
|
+
("exception_class", models.CharField(max_length=255)),
|
|
62
|
+
("message", models.TextField(default="")),
|
|
63
|
+
("traceback", models.TextField(default="")),
|
|
64
|
+
("created_at", models.DateTimeField(auto_now_add=True)),
|
|
65
|
+
(
|
|
66
|
+
"job",
|
|
67
|
+
models.OneToOneField(
|
|
68
|
+
on_delete=django.db.models.deletion.CASCADE,
|
|
69
|
+
related_name="failed_execution",
|
|
70
|
+
to="dj_queue.job",
|
|
71
|
+
),
|
|
72
|
+
),
|
|
73
|
+
],
|
|
74
|
+
options={
|
|
75
|
+
"db_table": "dj_queue_failed_executions",
|
|
76
|
+
},
|
|
77
|
+
),
|
|
78
|
+
migrations.CreateModel(
|
|
79
|
+
name="Process",
|
|
80
|
+
fields=[
|
|
81
|
+
(
|
|
82
|
+
"id",
|
|
83
|
+
models.BigAutoField(
|
|
84
|
+
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
85
|
+
),
|
|
86
|
+
),
|
|
87
|
+
("kind", models.CharField(max_length=32)),
|
|
88
|
+
("pid", models.IntegerField()),
|
|
89
|
+
("hostname", models.CharField(max_length=255)),
|
|
90
|
+
("name", models.CharField(max_length=255)),
|
|
91
|
+
("metadata", models.JSONField(default=dict)),
|
|
92
|
+
("last_heartbeat_at", models.DateTimeField()),
|
|
93
|
+
("created_at", models.DateTimeField(auto_now_add=True)),
|
|
94
|
+
(
|
|
95
|
+
"supervisor",
|
|
96
|
+
models.ForeignKey(
|
|
97
|
+
blank=True,
|
|
98
|
+
null=True,
|
|
99
|
+
on_delete=django.db.models.deletion.SET_NULL,
|
|
100
|
+
related_name="children",
|
|
101
|
+
to="dj_queue.process",
|
|
102
|
+
),
|
|
103
|
+
),
|
|
104
|
+
],
|
|
105
|
+
options={
|
|
106
|
+
"db_table": "dj_queue_processes",
|
|
107
|
+
},
|
|
108
|
+
),
|
|
109
|
+
migrations.CreateModel(
|
|
110
|
+
name="ClaimedExecution",
|
|
111
|
+
fields=[
|
|
112
|
+
(
|
|
113
|
+
"id",
|
|
114
|
+
models.BigAutoField(
|
|
115
|
+
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
116
|
+
),
|
|
117
|
+
),
|
|
118
|
+
("created_at", models.DateTimeField(auto_now_add=True)),
|
|
119
|
+
(
|
|
120
|
+
"job",
|
|
121
|
+
models.OneToOneField(
|
|
122
|
+
on_delete=django.db.models.deletion.CASCADE,
|
|
123
|
+
related_name="claimed_execution",
|
|
124
|
+
to="dj_queue.job",
|
|
125
|
+
),
|
|
126
|
+
),
|
|
127
|
+
(
|
|
128
|
+
"process",
|
|
129
|
+
models.ForeignKey(
|
|
130
|
+
blank=True,
|
|
131
|
+
null=True,
|
|
132
|
+
on_delete=django.db.models.deletion.SET_NULL,
|
|
133
|
+
related_name="claimed_executions",
|
|
134
|
+
to="dj_queue.process",
|
|
135
|
+
),
|
|
136
|
+
),
|
|
137
|
+
],
|
|
138
|
+
options={
|
|
139
|
+
"db_table": "dj_queue_claimed_executions",
|
|
140
|
+
},
|
|
141
|
+
),
|
|
142
|
+
migrations.CreateModel(
|
|
143
|
+
name="ReadyExecution",
|
|
144
|
+
fields=[
|
|
145
|
+
(
|
|
146
|
+
"id",
|
|
147
|
+
models.BigAutoField(
|
|
148
|
+
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
149
|
+
),
|
|
150
|
+
),
|
|
151
|
+
("queue_name", models.CharField(max_length=64)),
|
|
152
|
+
("priority", models.SmallIntegerField()),
|
|
153
|
+
("created_at", models.DateTimeField(auto_now_add=True)),
|
|
154
|
+
(
|
|
155
|
+
"job",
|
|
156
|
+
models.OneToOneField(
|
|
157
|
+
on_delete=django.db.models.deletion.CASCADE,
|
|
158
|
+
related_name="ready_execution",
|
|
159
|
+
to="dj_queue.job",
|
|
160
|
+
),
|
|
161
|
+
),
|
|
162
|
+
],
|
|
163
|
+
options={
|
|
164
|
+
"db_table": "dj_queue_ready_executions",
|
|
165
|
+
},
|
|
166
|
+
),
|
|
167
|
+
migrations.CreateModel(
|
|
168
|
+
name="ScheduledExecution",
|
|
169
|
+
fields=[
|
|
170
|
+
(
|
|
171
|
+
"id",
|
|
172
|
+
models.BigAutoField(
|
|
173
|
+
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
174
|
+
),
|
|
175
|
+
),
|
|
176
|
+
("queue_name", models.CharField(max_length=64)),
|
|
177
|
+
("priority", models.SmallIntegerField()),
|
|
178
|
+
("scheduled_at", models.DateTimeField()),
|
|
179
|
+
("created_at", models.DateTimeField(auto_now_add=True)),
|
|
180
|
+
(
|
|
181
|
+
"job",
|
|
182
|
+
models.OneToOneField(
|
|
183
|
+
on_delete=django.db.models.deletion.CASCADE,
|
|
184
|
+
related_name="scheduled_execution",
|
|
185
|
+
to="dj_queue.job",
|
|
186
|
+
),
|
|
187
|
+
),
|
|
188
|
+
],
|
|
189
|
+
options={
|
|
190
|
+
"db_table": "dj_queue_scheduled_executions",
|
|
191
|
+
},
|
|
192
|
+
),
|
|
193
|
+
migrations.CreateModel(
|
|
194
|
+
name="BlockedExecution",
|
|
195
|
+
fields=[
|
|
196
|
+
(
|
|
197
|
+
"id",
|
|
198
|
+
models.BigAutoField(
|
|
199
|
+
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
200
|
+
),
|
|
201
|
+
),
|
|
202
|
+
("queue_name", models.CharField(max_length=64)),
|
|
203
|
+
("priority", models.SmallIntegerField()),
|
|
204
|
+
("concurrency_key", models.CharField(max_length=255)),
|
|
205
|
+
("expires_at", models.DateTimeField()),
|
|
206
|
+
("created_at", models.DateTimeField(auto_now_add=True)),
|
|
207
|
+
(
|
|
208
|
+
"job",
|
|
209
|
+
models.OneToOneField(
|
|
210
|
+
on_delete=django.db.models.deletion.CASCADE,
|
|
211
|
+
related_name="blocked_execution",
|
|
212
|
+
to="dj_queue.job",
|
|
213
|
+
),
|
|
214
|
+
),
|
|
215
|
+
],
|
|
216
|
+
options={
|
|
217
|
+
"db_table": "dj_queue_blocked_executions",
|
|
218
|
+
"indexes": [
|
|
219
|
+
models.Index(
|
|
220
|
+
fields=["concurrency_key", "priority", "id"], name="dj_queue_bl_concurr_1ce730_idx"
|
|
221
|
+
),
|
|
222
|
+
models.Index(
|
|
223
|
+
fields=["expires_at", "concurrency_key"], name="dj_queue_bl_expires_ea27f7_idx"
|
|
224
|
+
),
|
|
225
|
+
],
|
|
226
|
+
},
|
|
227
|
+
),
|
|
228
|
+
migrations.AddIndex(
|
|
229
|
+
model_name="process",
|
|
230
|
+
index=models.Index(fields=["name", "supervisor"], name="dj_queue_pr_name_d374d8_idx"),
|
|
231
|
+
),
|
|
232
|
+
migrations.AddIndex(
|
|
233
|
+
model_name="process",
|
|
234
|
+
index=models.Index(fields=["last_heartbeat_at"], name="dj_queue_pr_last_he_813530_idx"),
|
|
235
|
+
),
|
|
236
|
+
migrations.AddConstraint(
|
|
237
|
+
model_name="process",
|
|
238
|
+
constraint=models.UniqueConstraint(
|
|
239
|
+
fields=("name", "supervisor"), name="dj_queue_processes_name_supervisor_unique"
|
|
240
|
+
),
|
|
241
|
+
),
|
|
242
|
+
migrations.AddIndex(
|
|
243
|
+
model_name="claimedexecution",
|
|
244
|
+
index=models.Index(fields=["process", "job"], name="dj_queue_cl_process_647400_idx"),
|
|
245
|
+
),
|
|
246
|
+
migrations.AddIndex(
|
|
247
|
+
model_name="readyexecution",
|
|
248
|
+
index=models.Index(fields=["priority", "id"], name="dj_queue_re_priorit_bfc737_idx"),
|
|
249
|
+
),
|
|
250
|
+
migrations.AddIndex(
|
|
251
|
+
model_name="readyexecution",
|
|
252
|
+
index=models.Index(
|
|
253
|
+
fields=["queue_name", "priority", "id"], name="dj_queue_re_queue_n_9931e4_idx"
|
|
254
|
+
),
|
|
255
|
+
),
|
|
256
|
+
migrations.AddIndex(
|
|
257
|
+
model_name="scheduledexecution",
|
|
258
|
+
index=models.Index(
|
|
259
|
+
fields=["scheduled_at", "priority", "id"], name="dj_queue_sc_schedul_7e8dd0_idx"
|
|
260
|
+
),
|
|
261
|
+
),
|
|
262
|
+
]
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Generated by Django 6.0.3 on 2026-04-06 15:16
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
dependencies = [
|
|
8
|
+
("dj_queue", "0001_initial"),
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
operations = [
|
|
12
|
+
migrations.CreateModel(
|
|
13
|
+
name="Pause",
|
|
14
|
+
fields=[
|
|
15
|
+
(
|
|
16
|
+
"id",
|
|
17
|
+
models.BigAutoField(
|
|
18
|
+
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
19
|
+
),
|
|
20
|
+
),
|
|
21
|
+
("queue_name", models.CharField(max_length=64, unique=True)),
|
|
22
|
+
("created_at", models.DateTimeField(auto_now_add=True)),
|
|
23
|
+
],
|
|
24
|
+
options={
|
|
25
|
+
"db_table": "dj_queue_pauses",
|
|
26
|
+
},
|
|
27
|
+
),
|
|
28
|
+
migrations.CreateModel(
|
|
29
|
+
name="Semaphore",
|
|
30
|
+
fields=[
|
|
31
|
+
(
|
|
32
|
+
"id",
|
|
33
|
+
models.BigAutoField(
|
|
34
|
+
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
35
|
+
),
|
|
36
|
+
),
|
|
37
|
+
("key", models.CharField(max_length=255, unique=True)),
|
|
38
|
+
("value", models.IntegerField()),
|
|
39
|
+
("limit", models.IntegerField()),
|
|
40
|
+
("expires_at", models.DateTimeField()),
|
|
41
|
+
("created_at", models.DateTimeField(auto_now_add=True)),
|
|
42
|
+
("updated_at", models.DateTimeField(auto_now=True)),
|
|
43
|
+
],
|
|
44
|
+
options={
|
|
45
|
+
"db_table": "dj_queue_semaphores",
|
|
46
|
+
"indexes": [
|
|
47
|
+
models.Index(fields=["key", "value"], name="dj_queue_se_key_7a5af2_idx"),
|
|
48
|
+
models.Index(fields=["expires_at"], name="dj_queue_se_expires_811b4d_idx"),
|
|
49
|
+
],
|
|
50
|
+
},
|
|
51
|
+
),
|
|
52
|
+
]
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Generated by Django 6.0.3 on 2026-04-06 15:34
|
|
2
|
+
|
|
3
|
+
import django.db.models.deletion
|
|
4
|
+
from django.db import migrations, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
dependencies = [
|
|
9
|
+
("dj_queue", "0002_pause_semaphore"),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.CreateModel(
|
|
14
|
+
name="RecurringTask",
|
|
15
|
+
fields=[
|
|
16
|
+
(
|
|
17
|
+
"id",
|
|
18
|
+
models.BigAutoField(
|
|
19
|
+
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
20
|
+
),
|
|
21
|
+
),
|
|
22
|
+
("key", models.CharField(max_length=255, unique=True)),
|
|
23
|
+
("task_path", models.CharField(max_length=255)),
|
|
24
|
+
("payload", models.JSONField(blank=True, null=True)),
|
|
25
|
+
("schedule", models.CharField(max_length=255)),
|
|
26
|
+
("queue_name", models.CharField(default="default", max_length=64)),
|
|
27
|
+
("priority", models.SmallIntegerField(default=0)),
|
|
28
|
+
("description", models.TextField(blank=True, default="")),
|
|
29
|
+
("static", models.BooleanField(default=False)),
|
|
30
|
+
("created_at", models.DateTimeField(auto_now_add=True)),
|
|
31
|
+
("updated_at", models.DateTimeField(auto_now=True)),
|
|
32
|
+
],
|
|
33
|
+
options={
|
|
34
|
+
"db_table": "dj_queue_recurring_tasks",
|
|
35
|
+
},
|
|
36
|
+
),
|
|
37
|
+
migrations.CreateModel(
|
|
38
|
+
name="RecurringExecution",
|
|
39
|
+
fields=[
|
|
40
|
+
(
|
|
41
|
+
"id",
|
|
42
|
+
models.BigAutoField(
|
|
43
|
+
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
44
|
+
),
|
|
45
|
+
),
|
|
46
|
+
("task_key", models.CharField(max_length=255)),
|
|
47
|
+
("run_at", models.DateTimeField()),
|
|
48
|
+
("created_at", models.DateTimeField(auto_now_add=True)),
|
|
49
|
+
(
|
|
50
|
+
"job",
|
|
51
|
+
models.OneToOneField(
|
|
52
|
+
blank=True,
|
|
53
|
+
null=True,
|
|
54
|
+
on_delete=django.db.models.deletion.CASCADE,
|
|
55
|
+
related_name="recurring_execution",
|
|
56
|
+
to="dj_queue.job",
|
|
57
|
+
),
|
|
58
|
+
),
|
|
59
|
+
],
|
|
60
|
+
options={
|
|
61
|
+
"db_table": "dj_queue_recurring_executions",
|
|
62
|
+
"indexes": [
|
|
63
|
+
models.Index(fields=["task_key", "run_at"], name="dj_queue_re_task_ke_8e21b4_idx")
|
|
64
|
+
],
|
|
65
|
+
"constraints": [
|
|
66
|
+
models.UniqueConstraint(
|
|
67
|
+
fields=("task_key", "run_at"),
|
|
68
|
+
name="dj_queue_recurring_executions_task_key_run_at_unique",
|
|
69
|
+
)
|
|
70
|
+
],
|
|
71
|
+
},
|
|
72
|
+
),
|
|
73
|
+
]
|
|
File without changes
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from dj_queue.models.jobs import (
|
|
2
|
+
BlockedExecution,
|
|
3
|
+
ClaimedExecution,
|
|
4
|
+
FailedExecution,
|
|
5
|
+
Job,
|
|
6
|
+
ReadyExecution,
|
|
7
|
+
ScheduledExecution,
|
|
8
|
+
)
|
|
9
|
+
from dj_queue.models.recurring import RecurringExecution, RecurringTask
|
|
10
|
+
from dj_queue.models.runtime import Pause, Process, Semaphore
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"BlockedExecution",
|
|
14
|
+
"ClaimedExecution",
|
|
15
|
+
"FailedExecution",
|
|
16
|
+
"Job",
|
|
17
|
+
"Pause",
|
|
18
|
+
"Process",
|
|
19
|
+
"ReadyExecution",
|
|
20
|
+
"RecurringExecution",
|
|
21
|
+
"RecurringTask",
|
|
22
|
+
"ScheduledExecution",
|
|
23
|
+
"Semaphore",
|
|
24
|
+
]
|