Repository: celery/celery

Issue:
Add documentation to the task_acks_on_failure_or_timeout setting
# Description

#4970 did not include the proper documentation for the setting.

# Suggestions

We should ensure to document it's behaviour before 4.3 GA.


Discussion:
@thedrow I submitted a PR based on the missing gaps I inferred from source code that used the `task_acks_on_failure_or_timeout` setting. I assume that the docs are built from the `celery.app.task` module so I applied my changes there.
The configuration documentation is at https://github.com/celery/celery/blob/master/docs/userguide/configuration.rst.
I'll copy what you added there.
Oh, seems like this was not introduced as a setting as well.
I'm going to do so now.

Resolving patch:
diff --git a/celery/app/defaults.py b/celery/app/defaults.py
--- a/celery/app/defaults.py
+++ b/celery/app/defaults.py
@@ -249,6 +249,7 @@ def __repr__(self):
     task=Namespace(
         __old__=OLD_NS,
         acks_late=Option(False, type='bool'),
+        acks_on_failure_or_timeout=Option(True, type='bool'),
         always_eager=Option(False, type='bool'),
         annotations=Option(type='any'),
         compression=Option(type='string', old={'celery_message_compression'}),
diff --git a/celery/app/task.py b/celery/app/task.py
--- a/celery/app/task.py
+++ b/celery/app/task.py
@@ -256,11 +256,12 @@ class Task(object):
     #: fails or times out.
     #:
     #: Configuring this setting only applies to tasks that are
-    #: acknowledged **after** they have been executed.
+    #: acknowledged **after** they have been executed and only if
+    #: :setting:`task_acks_late` is enabled.
     #:
     #: The application default can be overridden with the
     #: :setting:`task_acks_on_failure_or_timeout` setting.
-    acks_on_failure_or_timeout = True
+    acks_on_failure_or_timeout = None
 
     #: Even if :attr:`acks_late` is enabled, the worker will
     #: acknowledge tasks when the worker process executing them abruptly


Test patch:
diff --git a/t/unit/worker/test_request.py b/t/unit/worker/test_request.py
--- a/t/unit/worker/test_request.py
+++ b/t/unit/worker/test_request.py
@@ -616,9 +616,34 @@ def test_on_failure_acks_late(self):
         except KeyError:
             exc_info = ExceptionInfo()
             job.on_failure(exc_info)
-            assert job.acknowledged
+        assert job.acknowledged
+
+    def test_on_failure_acks_on_failure_or_timeout_disabled_for_task(self):
+        job = self.xRequest()
+        job.time_start = 1
+        self.mytask.acks_late = True
+        self.mytask.acks_on_failure_or_timeout = False
+        try:
+            raise KeyError('foo')
+        except KeyError:
+            exc_info = ExceptionInfo()
+            job.on_failure(exc_info)
+        assert job.acknowledged is False
+
+    def test_on_failure_acks_on_failure_or_timeout_enabled_for_task(self):
+        job = self.xRequest()
+        job.time_start = 1
+        self.mytask.acks_late = True
+        self.mytask.acks_on_failure_or_timeout = True
+        try:
+            raise KeyError('foo')
+        except KeyError:
+            exc_info = ExceptionInfo()
+            job.on_failure(exc_info)
+        assert job.acknowledged is True
 
-    def test_on_failure_acks_on_failure_or_timeout(self):
+    def test_on_failure_acks_on_failure_or_timeout_disabled(self):
+        self.app.conf.acks_on_failure_or_timeout = False
         job = self.xRequest()
         job.time_start = 1
         self.mytask.acks_late = True
@@ -628,7 +653,20 @@ def test_on_failure_acks_on_failure_or_timeout(self):
         except KeyError:
             exc_info = ExceptionInfo()
             job.on_failure(exc_info)
-            assert job.acknowledged is False
+        assert job.acknowledged is False
+        self.app.conf.acks_on_failure_or_timeout = True
+
+    def test_on_failure_acks_on_failure_or_timeout_enabled(self):
+        self.app.conf.acks_on_failure_or_timeout = True
+        job = self.xRequest()
+        job.time_start = 1
+        self.mytask.acks_late = True
+        try:
+            raise KeyError('foo')
+        except KeyError:
+            exc_info = ExceptionInfo()
+            job.on_failure(exc_info)
+        assert job.acknowledged is True
 
     def test_from_message_invalid_kwargs(self):
         m = self.TaskMessage(self.mytask.name, args=(), kwargs='foo')