# Revoking Tasks in Celery

Sometimes you need to cancel a task that has already been submitted or is currently executing. Celery provides the `revoke` command for this purpose.

## 1. Getting the Task ID

To revoke a task, you need its ID. This ID is returned when you call the task.

```python
from tasks import long_running_task

# Start the task
result = long_running_task.delay(10)
task_id = result.id

print(f"Task started with ID: {task_id}")
```

## 2. Revoking a Pending Task

If the task is still in the queue (waiting for a worker), you can revoke it. When a worker picks it up, it will see the revocation flag and discard the task without executing it.

```python
from tasks import app

# Revoke using the Celery app instance
app.control.revoke(task_id)
```

## 3. Revoking a Running Task (Termination)

If the task is **already executing** inside a worker, a standard `revoke` will not stop it. You must set `terminate=True`.

```python
app.control.revoke(task_id, terminate=True)
```

### Specifying Signals

By default, `terminate=True` sends the `SIGTERM` signal. You can specify a different signal, such as `SIGKILL`, if the task refuses to stop.

```python
import signal

app.control.revoke(task_id, terminate=True, signal=signal.SIGKILL)
```

*Warning: Terminating a task mid-execution can leave your data in an inconsistent state or leave resources (like file handles) open. Use with caution.*

## 4. Persistent Revocations

By default, the list of revoked tasks is stored in the memory of the workers. If a worker restarts, it forgets which tasks were revoked.

To make revocations persist across restarts, you must configure a persistent state for the workers.

Start the worker with the `-S` (statedb) flag:

```bash
celery -A tasks worker -S /var/run/celery/worker.state
```

[[programming/python/celery]]