diff --git a/django_q/tasks.py b/django_q/tasks.py index e256429..17bb204 100644 --- a/django_q/tasks.py +++ b/django_q/tasks.py @@ -148,7 +148,7 @@ def result(task_id, wait=0, cached=Conf.CACHED): start = time() while True: r = Task.get_result(task_id) - if r: + if r is not None: return r if (time() - start) * 1000 >= wait >= 0: break diff --git a/django_q/tests/tasks.py b/django_q/tests/tasks.py index 9e8a298..a189cdc 100644 --- a/django_q/tests/tasks.py +++ b/django_q/tests/tasks.py @@ -46,6 +46,10 @@ def hello(): return "hello" +def return_falsy_value(): + return [] + + def result(obj): print(f"RESULT HOOK {obj.name} : {obj.result()}") diff --git a/django_q/tests/test_cluster.py b/django_q/tests/test_cluster.py index 7ea7e4c..f313022 100644 --- a/django_q/tests/test_cluster.py +++ b/django_q/tests/test_cluster.py @@ -141,6 +141,30 @@ def test_cluster(broker): broker.delete_queue() +@pytest.mark.django_db +def test_results(broker): + broker.list_key = "cluster_test:q" + broker.delete_queue() + a = async_task( + "django_q.tests.tasks.return_falsy_value", + broker=broker, + ) + + task_queue = Queue() + stop_event = Event() + stop_event.set() + pusher(task_queue, stop_event, broker=broker) + task_queue.put("STOP") + result_queue = Queue() + worker(task_queue, result_queue, Value("f", -1)) + result_queue.put("STOP") + monitor(result_queue) + + # should not loop indefinitely when a real value is returned + value = result(a, wait=-1) + assert value == [] + + @pytest.mark.django_db def test_enqueue(broker, admin_user): broker.list_key = "cluster_test:q" diff --git a/docs/tasks.rst b/docs/tasks.rst index 0c5f2cb..7365ff8 100644 --- a/docs/tasks.rst +++ b/docs/tasks.rst @@ -121,6 +121,7 @@ Optionally you can use the :class:`AsyncTask` class to instantiate a task and ke a.run() # wait indefinitely for the result and print it + # don't let the task return `None` or it will wait indefinitely print(a.result(wait=-1)) # change the args @@ -264,7 +265,7 @@ Reference Gets the result of a previously executed task :param str task_id: the uuid or name of the task - :param int wait: optional milliseconds to wait for a result. -1 for indefinite + :param int wait: optional milliseconds to wait for a result. -1 for indefinite, but be sure the result will not be `None` otherwise it will wait indefinitely! :param bool cached: run this against the cache backend. :returns: The result of the executed task