mirror of
https://github.com/django/django.git
synced 2025-09-17 22:49:35 +00:00
This removes the ability to configure Task enqueueing via a setting, since the proposed `ENQUEUE_ON_COMMIT` did not support multi-database setups. Thanks to Simon Charette for the report. Follow-up to 4289966d1b8e848e5e460b7c782dac009d746b20.
432 lines
13 KiB
Plaintext
432 lines
13 KiB
Plaintext
=====
|
|
Tasks
|
|
=====
|
|
|
|
.. versionadded:: 6.0
|
|
|
|
.. module:: django.tasks
|
|
:synopsis: Django's built-in background Task system.
|
|
|
|
Task definition
|
|
===============
|
|
|
|
The ``task`` decorator
|
|
----------------------
|
|
|
|
.. function:: task(*, priority=0, queue_name="default", backend="default", takes_context=False)
|
|
|
|
The ``@task`` decorator defines a :class:`Task` instance. This has the
|
|
following optional arguments:
|
|
|
|
* ``priority``: Sets the :attr:`~Task.priority` of the ``Task``. Defaults
|
|
to 0.
|
|
* ``queue_name``: Sets the :attr:`~Task.queue_name` of the ``Task``.
|
|
Defaults to ``"default"``.
|
|
* ``backend``: Sets the :attr:`~Task.backend` of the ``Task``. Defaults to
|
|
``"default"``.
|
|
* ``takes_context``: Controls whether the ``Task`` function accepts a
|
|
:class:`TaskContext`. Defaults to ``False``. See :ref:`Task context
|
|
<task-context>` for details.
|
|
|
|
If the defined ``Task`` is not valid according to the backend,
|
|
:exc:`~django.tasks.exceptions.InvalidTask` is raised.
|
|
|
|
See :ref:`defining tasks <defining-tasks>` for usage examples.
|
|
|
|
``Task``
|
|
--------
|
|
|
|
.. class:: Task
|
|
|
|
Represents a Task to be run in the background. Tasks should be defined
|
|
using the :func:`task` decorator.
|
|
|
|
Attributes of ``Task`` cannot be modified. See :ref:`modifying Tasks
|
|
<modifying-tasks>` for details.
|
|
|
|
.. attribute:: Task.priority
|
|
|
|
The priority of the ``Task``. Priorities must be between -100 and 100,
|
|
where larger numbers are higher priority, and will be run sooner.
|
|
|
|
The backend must have :attr:`.supports_priority` set to ``True`` to use
|
|
this feature.
|
|
|
|
.. attribute:: Task.backend
|
|
|
|
The alias of the backend the ``Task`` should be enqueued to. This must
|
|
match a backend defined in :setting:`BACKEND <TASKS-BACKEND>`.
|
|
|
|
.. attribute:: Task.queue_name
|
|
|
|
The name of the queue the ``Task`` will be enqueued on to. Defaults to
|
|
``"default"``. This must match a queue defined in
|
|
:setting:`QUEUES <TASKS-QUEUES>`, unless
|
|
:setting:`QUEUES <TASKS-QUEUES>` is set to ``[]``.
|
|
|
|
.. attribute:: Task.run_after
|
|
|
|
The earliest time the ``Task`` will be executed. This can be a
|
|
:class:`timedelta <datetime.timedelta>`, which is used relative to the
|
|
current time, a timezone-aware :class:`datetime <datetime.datetime>`,
|
|
or ``None`` if not constrained. Defaults to ``None``.
|
|
|
|
The backend must have :attr:`.supports_defer` set to ``True`` to use
|
|
this feature. Otherwise,
|
|
:exc:`~django.tasks.exceptions.InvalidTask` is raised.
|
|
|
|
.. attribute:: Task.name
|
|
|
|
The name of the function decorated with :func:`task`. This name is not
|
|
necessarily unique.
|
|
|
|
.. method:: Task.using(*, priority=None, backend=None, queue_name=None, run_after=None)
|
|
|
|
Creates a new ``Task`` with modified defaults. The existing ``Task`` is
|
|
left unchanged.
|
|
|
|
``using`` allows modifying the following attributes:
|
|
|
|
* :attr:`priority <Task.priority>`
|
|
* :attr:`backend <Task.backend>`
|
|
* :attr:`queue_name <Task.queue_name>`
|
|
* :attr:`run_after <Task.run_after>`
|
|
|
|
See :ref:`modifying Tasks <modifying-tasks>` for usage examples.
|
|
|
|
.. method:: Task.enqueue(*args, **kwargs)
|
|
|
|
Enqueues the ``Task`` to the ``Task`` backend for later execution.
|
|
|
|
Arguments are passed to the ``Task``'s function after a round-trip
|
|
through a :func:`json.dumps`/:func:`json.loads` cycle. Hence, all
|
|
arguments must be JSON-serializable and preserve their type after the
|
|
round-trip.
|
|
|
|
If the ``Task`` is not valid according to the backend,
|
|
:exc:`~django.tasks.exceptions.InvalidTask` is raised.
|
|
|
|
See :ref:`enqueueing Tasks <enqueueing-tasks>` for usage examples.
|
|
|
|
.. method:: Task.aenqueue(*args, **kwargs)
|
|
|
|
The ``async`` variant of :meth:`enqueue <Task.enqueue>`.
|
|
|
|
.. method:: Task.get_result(result_id)
|
|
|
|
Retrieves a result by its id.
|
|
|
|
If the result does not exist, :exc:`TaskResultDoesNotExist
|
|
<django.tasks.exceptions.TaskResultDoesNotExist>` is raised. If the
|
|
result is not the same type as the current Task,
|
|
:exc:`TaskResultMismatch <django.tasks.exceptions.TaskResultMismatch>`
|
|
is raised. If the backend does not support ``get_result()``,
|
|
:exc:`NotImplementedError` is raised.
|
|
|
|
.. method:: Task.aget_result(*args, **kwargs)
|
|
|
|
The ``async`` variant of :meth:`get_result <Task.get_result>`.
|
|
|
|
Task context
|
|
============
|
|
|
|
.. class:: TaskContext
|
|
|
|
Contains context for the running :class:`Task`. Context only passed to a
|
|
``Task`` if it was defined with ``takes_context=True``.
|
|
|
|
Attributes of ``TaskContext`` cannot be modified.
|
|
|
|
.. attribute:: TaskContext.task_result
|
|
|
|
The :class:`TaskResult` currently being run.
|
|
|
|
.. attribute:: TaskContext.attempt
|
|
|
|
The number of the current execution attempts for this Task, starting at
|
|
1.
|
|
|
|
Task results
|
|
============
|
|
|
|
.. class:: TaskResultStatus
|
|
|
|
An Enum representing the status of a :class:`TaskResult`.
|
|
|
|
.. attribute:: TaskResultStatus.READY
|
|
|
|
The :class:`Task` has just been enqueued, or is ready to be executed
|
|
again.
|
|
|
|
.. attribute:: TaskResultStatus.RUNNING
|
|
|
|
The :class:`Task` is currently being executed.
|
|
|
|
.. attribute:: TaskResultStatus.FAILED
|
|
|
|
The :class:`Task` raised an exception during execution, or was unable
|
|
to start.
|
|
|
|
.. attribute:: TaskResultStatus.SUCCESSFUL
|
|
|
|
The :class:`Task` has finished executing successfully.
|
|
|
|
.. class:: TaskResult
|
|
|
|
The ``TaskResult`` stores the information about a specific execution of a
|
|
:class:`Task`.
|
|
|
|
Attributes of ``TaskResult`` cannot be modified.
|
|
|
|
.. attribute:: TaskResult.task
|
|
|
|
The :class:`Task` the result was enqueued for.
|
|
|
|
.. attribute:: TaskResult.id
|
|
|
|
A unique identifier for the result, which can be passed to
|
|
:meth:`Task.get_result`.
|
|
|
|
The format of the id will depend on the backend being used. Task result
|
|
ids are always strings less than 64 characters.
|
|
|
|
See :ref:`Task results <task-results>` for more details.
|
|
|
|
.. attribute:: TaskResult.status
|
|
|
|
The :class:`status <TaskResultStatus>` of the result.
|
|
|
|
.. attribute:: TaskResult.enqueued_at
|
|
|
|
The time when the ``Task`` was enqueued.
|
|
|
|
.. attribute:: TaskResult.started_at
|
|
|
|
The time when the ``Task`` began execution, on its first attempt.
|
|
|
|
.. attribute:: TaskResult.last_attempted_at
|
|
|
|
The time when the most recent ``Task`` run began execution.
|
|
|
|
.. attribute:: TaskResult.finished_at
|
|
|
|
The time when the ``Task`` finished execution, whether it failed or
|
|
succeeded.
|
|
|
|
.. attribute:: TaskResult.backend
|
|
|
|
The backend the result is from.
|
|
|
|
.. attribute:: TaskResult.errors
|
|
|
|
A list of :class:`TaskError` instances for the errors raised as part of
|
|
each execution of the Task.
|
|
|
|
.. attribute:: TaskResult.return_value
|
|
|
|
The return value from the ``Task`` function.
|
|
|
|
If the ``Task`` did not finish successfully, :exc:`ValueError` is
|
|
raised.
|
|
|
|
See :ref:`return values <task-return-values>` for usage examples.
|
|
|
|
.. method:: TaskResult.refresh
|
|
|
|
Refresh the result's attributes from the queue store.
|
|
|
|
.. method:: TaskResult.arefresh
|
|
|
|
The ``async`` variant of :meth:`TaskResult.refresh`.
|
|
|
|
.. attribute:: TaskResult.is_finished
|
|
|
|
Whether the ``Task`` has finished (successfully or not).
|
|
|
|
.. attribute:: TaskResult.attempts
|
|
|
|
The number of times the Task has been run.
|
|
|
|
If the task is currently running, it does not count as an attempt.
|
|
|
|
.. attribute:: TaskResult.worker_ids
|
|
|
|
The ids of the workers which have executed the Task.
|
|
|
|
|
|
Task errors
|
|
-----------
|
|
|
|
.. class:: TaskError
|
|
|
|
Contains information about the error raised during the execution of a
|
|
``Task``.
|
|
|
|
.. attribute:: TaskError.traceback
|
|
|
|
The traceback (as a string) from the raised exception when the ``Task``
|
|
failed.
|
|
|
|
.. attribute:: TaskError.exception_class
|
|
|
|
The exception class raised when executing the ``Task``.
|
|
|
|
Backends
|
|
========
|
|
|
|
Base backend
|
|
------------
|
|
|
|
.. module:: django.tasks.backends.base
|
|
|
|
.. class:: BaseTaskBackend
|
|
|
|
``BaseTaskBackend`` is the parent class for all Task backends.
|
|
|
|
.. attribute:: BaseTaskBackend.options
|
|
|
|
A dictionary of extra parameters for the Task backend. These are
|
|
provided using the :setting:`OPTIONS <TASKS-OPTIONS>` setting.
|
|
|
|
.. method:: BaseTaskBackend.enqueue(task, args, kwargs)
|
|
|
|
Task backends which subclass ``BaseTaskBackend`` should implement this
|
|
method as a minimum.
|
|
|
|
When implemented, ``enqueue()`` enqueues the ``task``, a :class:`.Task`
|
|
instance, for later execution. ``args`` are the positional arguments
|
|
and ``kwargs`` are the keyword arguments to be passed to the ``task``.
|
|
Returns a :class:`~django.tasks.TaskResult`.
|
|
|
|
.. method:: BaseTaskBackend.aenqueue(task, args, kwargs)
|
|
|
|
The ``async`` variant of :meth:`BaseTaskBackend.enqueue`.
|
|
|
|
.. method:: BaseTaskBackend.get_result(result_id)
|
|
|
|
Retrieve a result by its id. If the result does not exist,
|
|
:exc:`TaskResultDoesNotExist
|
|
<django.tasks.exceptions.TaskResultDoesNotExist>` is raised.
|
|
|
|
If the backend does not support ``get_result()``,
|
|
:exc:`NotImplementedError` is raised.
|
|
|
|
.. method:: BaseTaskBackend.aget_result(result_id)
|
|
|
|
The ``async`` variant of :meth:`BaseTaskBackend.get_result`.
|
|
|
|
.. method:: BaseTaskBackend.validate_task(task)
|
|
|
|
Validates whether the provided ``Task`` is able to be enqueued using
|
|
the backend. If the Task is not valid,
|
|
:exc:`InvalidTask <django.tasks.exceptions.InvalidTask>`
|
|
is raised.
|
|
|
|
Feature flags
|
|
~~~~~~~~~~~~~
|
|
|
|
Some backends may not support all features Django provides. It's possible to
|
|
identify the supported functionality of a backend, and potentially change
|
|
behavior accordingly.
|
|
|
|
.. attribute:: BaseTaskBackend.supports_defer
|
|
|
|
Whether the backend supports enqueueing Tasks to be executed after a
|
|
specific time using the :attr:`~django.tasks.Task.run_after` attribute.
|
|
|
|
.. attribute:: BaseTaskBackend.supports_async_task
|
|
|
|
Whether the backend supports enqueueing async functions (coroutines).
|
|
|
|
.. attribute:: BaseTaskBackend.supports_get_result
|
|
|
|
Whether the backend supports retrieving ``Task`` results from another
|
|
thread after they have been enqueued.
|
|
|
|
.. attribute:: BaseTaskBackend.supports_priority
|
|
|
|
Whether the backend supports executing Tasks as ordered by their
|
|
:attr:`~django.tasks.Task.priority`.
|
|
|
|
The below table notes which of the :ref:`built-in backends
|
|
<task-available-backends>` support which features:
|
|
|
|
============================ ======================= ===========================
|
|
Feature :class:`.DummyBackend` :class:`.ImmediateBackend`
|
|
============================ ======================= ===========================
|
|
:attr:`.supports_defer` Yes No
|
|
:attr:`.supports_async_task` Yes Yes
|
|
:attr:`.supports_get_result` No No [#fnimmediateresult]_
|
|
:attr:`.supports_priority` Yes [#fndummypriority]_ Yes [#fnimmediatepriority]_
|
|
============================ ======================= ===========================
|
|
|
|
.. _task-available-backends:
|
|
|
|
Available backends
|
|
------------------
|
|
|
|
Immediate backend
|
|
~~~~~~~~~~~~~~~~~
|
|
|
|
.. module:: django.tasks.backends.immediate
|
|
|
|
.. class:: ImmediateBackend
|
|
|
|
The :ref:`immediate backend <immediate-task-backend>` executes Tasks
|
|
immediately, rather than in the background.
|
|
|
|
Dummy backend
|
|
~~~~~~~~~~~~~
|
|
|
|
.. module:: django.tasks.backends.dummy
|
|
|
|
.. class:: DummyBackend
|
|
|
|
The :ref:`dummy backend <dummy-task-backend>` does not execute enqueued
|
|
Tasks. Instead, it stores task results for later inspection.
|
|
|
|
.. attribute:: DummyBackend.results
|
|
|
|
A list of results for the enqueued Tasks, in the order they were
|
|
enqueued.
|
|
|
|
.. method:: DummyBackend.clear
|
|
|
|
Clears the list of stored results.
|
|
|
|
Exceptions
|
|
==========
|
|
|
|
.. module:: django.tasks.exceptions
|
|
|
|
.. exception:: InvalidTask
|
|
|
|
Raised when the :class:`.Task` attempting to be enqueued
|
|
is invalid.
|
|
|
|
.. exception:: InvalidTaskBackend
|
|
|
|
Raised when the requested :class:`.BaseTaskBackend` is invalid.
|
|
|
|
.. exception:: TaskResultDoesNotExist
|
|
|
|
Raised by :meth:`~django.tasks.backends.base.BaseTaskBackend.get_result`
|
|
when the provided ``result_id`` does not exist.
|
|
|
|
.. exception:: TaskResultMismatch
|
|
|
|
Raised by :meth:`~django.tasks.Task.get_result` when the provided
|
|
``result_id`` is for a different Task than the current Task.
|
|
|
|
.. rubric:: Footnotes
|
|
.. [#fnimmediateresult] The :class:`.ImmediateBackend` doesn't officially
|
|
support ``get_result()``, despite implementing the API, since the result
|
|
cannot be retrieved from a different thread.
|
|
.. [#fndummypriority] The :class:`.DummyBackend` has ``supports_priority=True``
|
|
so that it can be used as a drop-in replacement in tests. Since this
|
|
backend never executes Tasks, the ``priority`` value has no effect.
|
|
.. [#fnimmediatepriority] The :class:`.ImmediateBackend` has
|
|
``supports_priority=True`` so that it can be used as a drop-in replacement
|
|
in tests. Because Tasks run as soon as they are scheduled, the ``priority``
|
|
value has no effect.
|