Description
- What is the current behavior?
When a Python program calls self.update_state()
, this package will return that state as the completed result, rather than waiting for a SUCCESS, FAILURE, or REVOKED.
As an example Python program which pretends to do work with a progress update:
from celery import Celery
import time
app = Celery('tasks')
app.config_from_object('celeryconfig')
@app.task(bind=True)
def add(self, x, y):
print(f"Got task : {x} + {y}")
# wait for a short while before sending progress
print("Sleeping 5 ...")
time.sleep(5)
self.update_state(state="PROGRESS", meta={ 'progress': 51 })
# wait for a little more before returning the result
print("Sleeping 3 ...")
time.sleep(3)
print(f"Returning result {x+y}")
return x + y
Then, my node.js program waits for the result, but instead stops when it gets the progress:
import celery from 'celery-node'
const client = celery.createClient("redis://", "redis://")
const x = Math.floor(Math.random() * 100)
const y = Math.floor(Math.random() * 100)
console.log(`Sending ${x} and ${y}`)
const task = client.createTask("tasks.add")
const result = task.applyAsync([], { x, y })
result.get().then(result => {
console.log('result:', result)
console.log('Disconnecting ...')
client.disconnect()
})
Output (showing the 500ms between each check):
$ node celery-node--add-task-and-wait-for-result.js
Sending 24 and 42
meta: null
(Previous message x9.)
meta: {
status: 'PROGRESS',
result: { progress: 51 },
traceback: null,
children: [],
task_id: '93ef8d1b-f8f8-413b-b17b-c046175b985b'
}
result: { progress: 51 }
Disconnecting ...
- What is the expected behavior?
The expected behaviour is that we can see the progress but we wait for the result:
$ node celery-node--add-task-and-wait-for-result.js
Sending 80 and 4
meta: null
(Previous message x9.)
meta: {
status: 'SUCCESS',
result: 84,
traceback: null,
children: [],
task_id: '54e2ec1c-38bd-4254-b558-8e0d92a6a28b'
}
(Previous message x6.)
result: 84
Disconnecting ...
To do this, I have changed line 44 of src/app/result.ts
so that it checks the status before returning:
diff --git a/src/app/result.ts b/src/app/result.ts
index ce979f6..b9ff2d7 100644
--- a/src/app/result.ts
+++ b/src/app/result.ts
@@ -41,7 +41,7 @@ export class AsyncResult {
intervalId = setInterval(() => {
this.backend.getTaskMeta(this.taskId).then(meta => {
- if (meta) {
+ if (meta && ["SUCCESS", "FAILURE", "REVOKED"].includes(meta["status"])) {
if (timeout) {
clearTimeout(timeoutId);
}
i.e. if the task result is put into the queue without any progress or other updated state (just the final result) it's fine, but not in the case where there is updated state.
-
Please tell us about your environment:
- Version: 0.5.3
- OS: Ubuntu 18.04
Linux ryloth 4.15.0-126-generic #129-Ubuntu SMP Mon Nov 23 18:53:38 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
- Language: ES5
-
Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow, gitter, etc)
I mentioned the fix above and I'm happy to submit a PR. I'm also happy to refactor slightly just so the check for the status is moved out somewhere else since it would exist three times in that file with this new addition:
["SUCCESS", "FAILURE", "REVOKED"].includes(meta["status"])
Many thanks for this package.