From d55d33ce27921378a5d4fd5fcc81b98b3b761919 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Janne=20R=C3=B6nkk=C3=B6?= Date: Wed, 6 Feb 2019 16:49:09 +0200 Subject: [PATCH] Document the behaviour of retry value properly This issue has been reported many times in Django-Q's issue tracker: https://github.com/Koed00/django-q/issues/183 https://github.com/Koed00/django-q/issues/180 https://github.com/Koed00/django-q/issues/307 All these issue have been closed and responses have noted that retry should be set bigger than timeout or duration of any task. --- docs/configure.rst | 33 +++++++++++++++++++++++++++++++++ docs/tasks.rst | 2 ++ 2 files changed, 35 insertions(+) diff --git a/docs/configure.rst b/docs/configure.rst index 824ef83..ddf749c 100644 --- a/docs/configure.rst +++ b/docs/configure.rst @@ -59,6 +59,8 @@ timeout The number of seconds a worker is allowed to spend on a task before it's terminated. Defaults to ``None``, meaning it will never time out. Set this to something that makes sense for your project. Can be overridden for individual tasks. +See :ref:`retry` for details how to set values for timeout and retry. + .. _ack_failures: ack_failures @@ -74,6 +76,37 @@ retry The number of seconds a broker will wait for a cluster to finish a task, before it's presented again. Only works with brokers that support delivery receipts. Defaults to 60 seconds. +The value must be bigger than the time it takes to complete longest task, i.e. :ref:`timeout` must be less than retry value and all tasks must complete +in less time than the selected retry time. If this does not hold, i.e. the retry value is less than timeout or less than it takes to finish a task, +Django-Q will start the task again if the used broker supports receipts. + +For example, with the following code + +.. code:: python + + # settings.py + Q_CLUSTER = { + 'retry': 5 + 'workers': 4, + 'orm': 'default', + } + + # example.py + + from django_q.tasks import async_task + + async_task('time.sleep', 22) + +First, ``time.sleep`` is called by the first worker. After 5 seconds second worker will also call ``time.sleep`` because retry time has exceeded and the +broker return the task again for the cluster. After 21 seconds from the call to ``async_task`` all four workers are running the ``time.sleep(22)`` call +and there is one retry in queue; tasks are started after 0, 5, 10, 15 and 20 seconds after the ``async_task`` was called. After 22 seconds the first +worker completes and the task is acknowledged in the broker and the task is not added to task queue anymore but the task that was already in the run queue +will run also. So in this example, ``time.sleep`` was called 5 times. + +Note also that the above issue might cause all workers to run the same long running task preventing new tasks from starting shortly after the task has been +started by ``async_task``. In this case the retry time handling could cause the task that has not been started by any worker to be put on work queue again +(even multiple times). + compress ~~~~~~~~ diff --git a/docs/tasks.rst b/docs/tasks.rst index f0004df..d631cdc 100644 --- a/docs/tasks.rst +++ b/docs/tasks.rst @@ -57,6 +57,8 @@ timeout """"""" Overrides the cluster's timeout setting for this task. +See :ref:`retry` for details how to set values for timeout. + ack_failure """"""""""" Overrides the cluster's :ref:`ack_failures` setting for this task.