dj-queue 0.6.2__tar.gz → 0.6.3__tar.gz
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-0.6.2 → dj_queue-0.6.3}/PKG-INFO +1 -1
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/admin.py +44 -1
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/operations/jobs.py +39 -2
- {dj_queue-0.6.2 → dj_queue-0.6.3}/pyproject.toml +1 -1
- {dj_queue-0.6.2 → dj_queue-0.6.3}/LICENSE +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/README.md +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/__init__.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/api.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/apps.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/backend.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/config.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/contrib/__init__.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/contrib/asgi.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/contrib/gunicorn.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/contrib/prometheus.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/dashboard.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/db.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/exceptions.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/hooks.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/log.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/management/__init__.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/management/commands/__init__.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/management/commands/dj_queue.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/management/commands/dj_queue_health.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/management/commands/dj_queue_prune.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/migrations/0001_initial.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/migrations/0002_pause_semaphore.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/migrations/0003_recurringtask_recurringexecution.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/migrations/0004_dashboard.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/migrations/0005_remove_recurringexecution_dj_queue_recurring_executions_task_key_run_at_unique_and_more.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/migrations/__init__.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/models/__init__.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/models/jobs.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/models/recurring.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/models/runtime.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/observability.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/operations/__init__.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/operations/_insert.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/operations/cleanup.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/operations/concurrency.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/operations/recurring.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/routers.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/runtime/__init__.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/runtime/base.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/runtime/dispatcher.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/runtime/errors.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/runtime/interruptible.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/runtime/notify.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/runtime/pidfile.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/runtime/pool.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/runtime/procline.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/runtime/scheduler.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/runtime/supervisor.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/runtime/worker.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/templates/admin/dj_queue/_dashboard_process_rows.html +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/templates/admin/dj_queue/_dashboard_recurring_rows.html +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/templates/admin/dj_queue/_dashboard_section_table.html +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/templates/admin/dj_queue/_dashboard_semaphore_rows.html +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/templates/admin/dj_queue/_paginator.html +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/templates/admin/dj_queue/_queue_controls.html +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/templates/admin/dj_queue/_sortable_header_cells.html +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/templates/admin/dj_queue/change_form.html +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/templates/admin/dj_queue/change_list.html +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/templates/admin/dj_queue/dashboard.html +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/templates/admin/dj_queue/includes/fieldset.html +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/templates/admin/dj_queue/queue_jobs.html +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/templatetags/__init__.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/templatetags/dj_queue_admin.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/urls.py +0 -0
- {dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/views.py +0 -0
|
@@ -28,7 +28,7 @@ from dj_queue.models import (
|
|
|
28
28
|
RecurringTask,
|
|
29
29
|
Semaphore,
|
|
30
30
|
)
|
|
31
|
-
from dj_queue.operations.jobs import enqueue_job_again
|
|
31
|
+
from dj_queue.operations.jobs import dispatch_scheduled_job_now, enqueue_job_again
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
class DjQueueFirstAdminSite(admin.AdminSite):
|
|
@@ -563,6 +563,16 @@ class JobAdmin(HiddenSidebarAdminMixin, admin.ModelAdmin):
|
|
|
563
563
|
def get_change_actions(self, request, obj):
|
|
564
564
|
if obj is None:
|
|
565
565
|
return ()
|
|
566
|
+
if obj.status == "scheduled":
|
|
567
|
+
return (
|
|
568
|
+
{"name": "run_now", "label": "Run now", "css_class": "djq-object-action-retry"},
|
|
569
|
+
{
|
|
570
|
+
"name": "enqueue_copy_now",
|
|
571
|
+
"label": "Enqueue copy now",
|
|
572
|
+
"css_class": "djq-object-action-retry",
|
|
573
|
+
},
|
|
574
|
+
)
|
|
575
|
+
|
|
566
576
|
actions = [{"name": "enqueue", "label": "Enqueue job", "css_class": "djq-object-action-retry"}]
|
|
567
577
|
if obj.status == "failed":
|
|
568
578
|
actions.extend(
|
|
@@ -582,6 +592,39 @@ class JobAdmin(HiddenSidebarAdminMixin, admin.ModelAdmin):
|
|
|
582
592
|
return tuple(actions)
|
|
583
593
|
|
|
584
594
|
def handle_change_action(self, request, obj, action):
|
|
595
|
+
if action == "run_now":
|
|
596
|
+
try:
|
|
597
|
+
_job, dispatched_as = dispatch_scheduled_job_now(obj.pk, backend_alias=obj.backend_alias)
|
|
598
|
+
except (EnqueueError, ImportError, AttributeError) as exc:
|
|
599
|
+
self.message_user(request, f"Could not dispatch job now: {exc}", level=messages.ERROR)
|
|
600
|
+
return self._current_object_redirect(obj, backend_alias=obj.backend_alias)
|
|
601
|
+
|
|
602
|
+
message = "Dispatched scheduled job for immediate execution"
|
|
603
|
+
if dispatched_as == "blocked":
|
|
604
|
+
message = "Dispatched scheduled job immediately and it is now blocked"
|
|
605
|
+
if dispatched_as == "discarded":
|
|
606
|
+
message = "Dispatched scheduled job immediately and it was discarded"
|
|
607
|
+
self.message_user(request, message, level=messages.SUCCESS)
|
|
608
|
+
return self._current_object_redirect(obj, backend_alias=obj.backend_alias)
|
|
609
|
+
|
|
610
|
+
if action == "enqueue_copy_now":
|
|
611
|
+
try:
|
|
612
|
+
new_job = enqueue_job_again(obj.pk, backend_alias=obj.backend_alias, run_after=None)
|
|
613
|
+
except (EnqueueError, ImportError, AttributeError) as exc:
|
|
614
|
+
self.message_user(request, f"Could not enqueue job: {exc}", level=messages.ERROR)
|
|
615
|
+
return self._current_object_redirect(obj, backend_alias=obj.backend_alias)
|
|
616
|
+
|
|
617
|
+
self.message_user(
|
|
618
|
+
request,
|
|
619
|
+
format_html(
|
|
620
|
+
'Enqueued immediate copy <a href="{}">{}</a>.',
|
|
621
|
+
self._change_url(object_id=new_job.pk, backend_alias=new_job.backend_alias),
|
|
622
|
+
new_job.pk,
|
|
623
|
+
),
|
|
624
|
+
level=messages.SUCCESS,
|
|
625
|
+
)
|
|
626
|
+
return self._current_object_redirect(obj, backend_alias=obj.backend_alias)
|
|
627
|
+
|
|
585
628
|
if action == "enqueue":
|
|
586
629
|
try:
|
|
587
630
|
new_job = enqueue_job_again(obj.pk, backend_alias=obj.backend_alias)
|
|
@@ -351,6 +351,39 @@ def promote_scheduled_jobs(*, batch_size, backend_alias="default", use_skip_lock
|
|
|
351
351
|
return jobs
|
|
352
352
|
|
|
353
353
|
|
|
354
|
+
def dispatch_scheduled_job_now(job_id, *, backend_alias="default"):
|
|
355
|
+
alias = get_database_alias(backend_alias)
|
|
356
|
+
config = load_backend_config(backend_alias)
|
|
357
|
+
|
|
358
|
+
with transaction.atomic(using=alias):
|
|
359
|
+
scheduled = locked_queryset(
|
|
360
|
+
ScheduledExecution.objects.using(alias)
|
|
361
|
+
.select_related("job")
|
|
362
|
+
.filter(job_id=job_id, job__backend_alias=backend_alias),
|
|
363
|
+
use_skip_locked=config.use_skip_locked,
|
|
364
|
+
).first()
|
|
365
|
+
if scheduled is None:
|
|
366
|
+
raise EnqueueError("job is not scheduled")
|
|
367
|
+
|
|
368
|
+
job = scheduled.job
|
|
369
|
+
scheduled.delete(using=alias)
|
|
370
|
+
job.scheduled_at = None
|
|
371
|
+
job.save(using=alias, update_fields=["scheduled_at", "updated_at"])
|
|
372
|
+
dispatched_as = _dispatch_existing_job(job)
|
|
373
|
+
|
|
374
|
+
if dispatched_as == "ready":
|
|
375
|
+
runtime_notify.notify_ready_queues((job.queue_name,), backend_alias=backend_alias)
|
|
376
|
+
|
|
377
|
+
log_event(
|
|
378
|
+
"job.dispatched_now",
|
|
379
|
+
job_id=str(job.id),
|
|
380
|
+
queue_name=job.queue_name,
|
|
381
|
+
priority=job.priority,
|
|
382
|
+
dispatched_as=dispatched_as,
|
|
383
|
+
)
|
|
384
|
+
return job, dispatched_as
|
|
385
|
+
|
|
386
|
+
|
|
354
387
|
def retry_failed_job(job_id, *, backend_alias="default"):
|
|
355
388
|
alias = get_database_alias(backend_alias)
|
|
356
389
|
|
|
@@ -370,15 +403,19 @@ def retry_failed_job(job_id, *, backend_alias="default"):
|
|
|
370
403
|
return job
|
|
371
404
|
|
|
372
405
|
|
|
373
|
-
|
|
406
|
+
_KEEP_RUN_AFTER = object()
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
def enqueue_job_again(job_id, *, backend_alias="default", run_after=_KEEP_RUN_AFTER):
|
|
374
410
|
alias = get_database_alias(backend_alias)
|
|
375
411
|
source_job = Job.objects.using(alias).get(pk=job_id)
|
|
376
412
|
task = import_string(source_job.task_path)
|
|
413
|
+
source_run_after = source_job.scheduled_at if run_after is _KEEP_RUN_AFTER else run_after
|
|
377
414
|
if hasattr(task, "using"):
|
|
378
415
|
task = task.using(
|
|
379
416
|
priority=source_job.priority,
|
|
380
417
|
queue_name=source_job.queue_name,
|
|
381
|
-
run_after=
|
|
418
|
+
run_after=source_run_after,
|
|
382
419
|
backend=source_job.backend_alias,
|
|
383
420
|
)
|
|
384
421
|
args = list(source_job.payload.get("args", []))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/migrations/0003_recurringtask_recurringexecution.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/templates/admin/dj_queue/_dashboard_process_rows.html
RENAMED
|
File without changes
|
{dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/templates/admin/dj_queue/_dashboard_recurring_rows.html
RENAMED
|
File without changes
|
{dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/templates/admin/dj_queue/_dashboard_section_table.html
RENAMED
|
File without changes
|
{dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/templates/admin/dj_queue/_dashboard_semaphore_rows.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dj_queue-0.6.2 → dj_queue-0.6.3}/dj_queue/templates/admin/dj_queue/_sortable_header_cells.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|