It is not possible to remove only one message in the queue other than removing them all with a purge or with a manual command in your broker.
However, you might not mind as a revoked task once processed by a worker is removed from the queue. So you don't have to maintain an eternal revoked id list.
You should keep an id on this list only while it has not been processed by a worker because the workers are busy or the task is scheduled for later.
The list should be persistent if all your workers could be stopped at the same time and you want to keep the flagged revoked tasks. Else, a new worker asks the already running workers about the tasks to flag as revoked.
Note: I analyzed a case with Redis as the broker and backend to get the answer. The task revoked was finally removed from the queue and visible as a result (marked as revoked).
Example:
- The task with id 'A' is pushed in the queue and scheduled for in 1 hour
- The task 'A' is
revoke() so a message is sent to all workers to flag the task as revoked. The id is in the revoke list of each worker (cf in log Tasks flagged as revoked: A)
- The task 'A' is still in the queue waiting for its ETA
- After one hour, a worker executes the task. As the task is flagged as revoked, the worker does not execute the task but immediately writes the task result in the backend. The result says that the task is revoked (so not executed).
I don't know about the exact reason why you can't directly remove tasks from the queue. But my intuitions are:
- All the brokers might not allow removing an element in the middle of the queue
- Removing a task immediately and letting the task system consistent is maybe harder. And as the Celery team has a limited workforce, they don't want to support something complex if a simpler solution does the job