===== 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 ` for details. If the defined ``Task`` is not valid according to the backend, :exc:`~django.tasks.exceptions.InvalidTask` is raised. See :ref:`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 ` 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 `. .. 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 `, unless :setting:`QUEUES ` is set to ``[]``. .. attribute:: Task.run_after The earliest time the ``Task`` will be executed. This can be a :class:`timedelta `, which is used relative to the current time, a timezone-aware :class:`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 ` * :attr:`backend ` * :attr:`queue_name ` * :attr:`run_after ` See :ref:`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 ` for usage examples. .. method:: Task.aenqueue(*args, **kwargs) The ``async`` variant of :meth:`enqueue `. .. method:: Task.get_result(result_id) Retrieves a result by its id. If the result does not exist, :exc:`TaskResultDoesNotExist ` is raised. If the result is not the same type as the current Task, :exc:`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 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 ` for more details. .. attribute:: TaskResult.status The :class:`status ` 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 ` 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 ` 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 ` 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 ` 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 ` 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 ` executes Tasks immediately, rather than in the background. Dummy backend ~~~~~~~~~~~~~ .. module:: django.tasks.backends.dummy .. class:: DummyBackend The :ref:`dummy 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.