Premise: it is necessary to perform the function of suspending (revoking) a task without affecting the continued execution of other tasks
Find out that celery 3.0 has the revoke function
The official document of celery describes revoke
Here is the test code
Django3.2.8 (this version is not important, but the following two are important)
django-celery3.3.1
celery==3.1.26.post2
If the two celery versions don't match, it's very troublesome to use
Django celery the biggest celery supported by this package seems to be celery 3
His Django celery has not been updated for a long time. There is a new one called Django celery base. I'll see it again when I have time
And an important point!!!
After forgetting python, async became a built-in keyword
The celery version is earlier, so it conflicts with the async keyword. If you can't upgrade / downgrade the python version
It is recommended to modify the async keyword in celery (I personally recommend this method. It is too cumbersome to upgrade / downgrade the python version, and there are other things that cannot be used if they are not guaranteed)
File "/home/lice/.local/lib/python3.8/site-packages/celery/utils/timer2.py", line 19 from kombu.async.timer import Entry, Timer as Schedule, to_timestamp, logger ^ SyntaxError: invalid syntax #We must see here. No matter how many lines of errors he pops up, find the async line and correct it for him
There's more to change
There's more to change
There's more to change
Just start the project several more times. He reports it and changes it once until there is no error (it's bullshit = = |)
Code function description
Publish the celery task, record the task id(task.id) and revoke(task.id) when the task is still running, and destroy it
Model file
Cellery under the project root directory
I use rabbitMQ here
redis, just match it like this
Let's start with tasks and views
from .tasks import * from Dw_test.celery import app # Here is your root directory (the setting directory) from django.http import HttpResponse from .models import Tasks from .tasks import * def ads(request, ls): tasks = test_app.apply_async(args=[ls]) # Remember the tasks, write down his ID and use it later print(tasks.id) Tasks.objects.create(task_id=tasks.id) # Database record operation return HttpResponse(tasks.id) def dels(req, ls): tasks_all = Tasks.objects.get(id=ls) app.control.revoke(tasks_all.task_id, terminate=True) # If you add it to terminate, it will not be revoked = =. You can also add a signal='SIGKILL ', but I can't measure the difference tasks_all.is_delete = True tasks_all.save() # It's all my database record operations return HttpResponse(tasks_all.task_id + " is delete")
views.py
from __future__ import absolute_import from time import sleep from billiard.exceptions import Terminated from celery import shared_task # Shared is recommended here_ Task, it can turn your task function into a global shared function. Task cannot. Task must also specify the target cell @shared_task(throws=(Terminated,)) # This terminated is useful here, as follows def test_app(x): print('-----Start-----') for i in range(x): sleep(1) print(i) print('-----Over-----')
Tasks.py (you have to build it manually under the app)
from django.urls import path from .views import * urlpatterns = [ path('task/<int:ls>', ads), path('task_del/<int:ls>', dels), ]
This is urls.py under app (built manually)
If all goes well, start celery
Command: cell - a project name worker -l info
Successfully visible ↓
Let's start the test
The larger the number, the longer the time. The one written earlier can be changed. The returned one is the task id
You can see that it has started running successfully
Now try to terminate this task
If there is no accident, an error will be reported and the task will be successfully cancelled
The solution is to add an exception to the task function (in task.py) I mentioned above
such
do it again
Successfully stopped
For the pause and start function, you can process the unfinished tasks from the database when starting by saving the unprocessed data in the database
Above~