mirror of
				https://github.com/django/django.git
				synced 2025-10-30 17:16:10 +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 4289966d1b.
		
	
		
			
				
	
	
		
			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.
 |