Decorators¶
exactly_once¶
django_periodic_tasks.decorators.exactly_once(func)Decorator ensuring a scheduled task runs at most once per invocation.
When :meth:~django_periodic_tasks.models.ScheduledTask.enqueue_now (used
by both the scheduler and the Django admin “Run now” action) creates a
TaskExecution row and passes its ID via the
_periodic_tasks_execution_id keyword argument, this decorator will:
- Pop
_periodic_tasks_execution_idfrom kwargs. - Lock the
TaskExecutionrow withSELECT FOR UPDATE. - Run the wrapped function only if the row’s status is
PENDING. - Mark the row
COMPLETEDon success.
If _periodic_tasks_execution_id is absent (e.g. manual invocation), the
wrapped function runs normally without any execution-permit logic.
.. warning::
This decorator is designed exclusively for tasks managed by
:class:~django_periodic_tasks.models.ScheduledTask. The
deduplication guarantee depends on
:func:~django_periodic_tasks.enqueue.enqueue_scheduled_task creating a
</span><span class="n">TaskExecution</span><span class="n n-Quoted"> row and injecting </span><span class="n">_periodic_tasks_execution_id</span><span class="n n-Quoted">
into the task kwargs before enqueue.
Calling a </span><span class="nv">@exactly_once</span><span class="n n-Quoted">-decorated task directly via
</span><span class="n">task</span><span class="p">.</span><span class="n">enqueue</span><span class="p">()</span><span class="n n-Quoted"> (bypassing </span><span class="n">ScheduledTask</span><span class="n n-Quoted">) will run the function
normally but without any deduplication protection.