Django中的线程无法在生产环境中使用 [英] Threading in Django is not working in production
问题描述
我的Django views.py中有一个类似这样的函数.
I have a function in my Django views.py that looks like this.
def process(request):
form = ProcessForm(request.POST, request.FILES)
if form.is_valid():
instance = form.save(commit=False)
instance.requested_by = request.user
instance.save()
t = threading.Thread(target=utils.background_match, args=(instance,), kwargs={})
t.setDaemon(True)
t.start()
return HttpResponseRedirect(reverse('mart:processing'))
在这里,我试图在提交ProcessForm时在单独的线程中调用函数"background_match".由于此线程需要一些时间才能完成,因此我将用户重定向到另一个名为"mart:processing"的页面.
Here, I'm trying to call a function 'background_match' in a separate thread when ProcessForm is submitted. Since this thread takes some time to complete, I redirect the user to another page named 'mart:processing'.
我面临的问题是,它们在我的本地计算机上都可以正常运行,但在作为AWS EC2实例的生产服务器上却无法正常工作.该线程根本无法启动. background_match函数内部有一个for循环,不会向前移动.
The problem I am facing is that it all works fine in my local machine but doesn't work on production server which is an AWS EC2 instance. The thread doesn't start at all. There's a for loop inside the background_match function which doesn't move forward.
但是,如果刷新(CTRL + R)"mart:processing"页面,它的确会移动1或2次迭代.因此,要运行一个包含1000个迭代的完整循环,我需要刷新页面1000次.例如,如果经过100次迭代,我不刷新页面,则该页面将停留在该位置,并且不会移至第101次迭代.请帮忙!
However, if I refresh (CTRL + R) the 'mart:processing' page, it does move by 1 or 2 iterations. So, for a complete loop consisting of 1000 iterations to run, I need to refresh the page 1000 times. If after, say, 100 iterations I don't refresh the page it gets stuck at that point and doesn't move to the 101st iteration. Please help!
推荐答案
错误的体系结构. Django和其他网络应用程序应生成此类线程.正确的方法是使用任务队列创建异步任务. django最受欢迎的任务队列恰巧是 Celery .
Wrong architecture. Django and other web apps should be spawning threads like this. The correct way is to create an async task using a task queue. The most popular task queue for django happens to be Celery.
然后,mart:processing
页应检查异步结果,以确定任务是否已完成.粗略的草图如下.
The mart:processing
page should then check the async result to determine if the task has been completed. A rough sketch is as follows.
from celery.result import AsynResult
from myapp.tasks import my_task
...
if form.is_valid():
...
task_id = my_task()
request.session['task_id']=task_id
return HttpResponseRedirect(reverse('mart:processing'))
...
在下一页
task_id = request.session.get('task_id')
if task_id:
task = AsyncResult(task_id)
这篇关于Django中的线程无法在生产环境中使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!