我的Django views.py中有一个看起来像这样的函数。
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'的页面。
我面临的问题是它在我的本地计算机上运行良好,但在生产服务器(AWS EC2实例)上不起作用。线程根本没有启动。在background_match函数中有一个for循环,它不会向前移动。
但是,如果我刷新(CTRL + R)'mart:processing'页面,它会移动1或2次迭代。因此,对于包含1000次迭代运行的完整循环,我需要刷新页面1000次。如果在100次迭代之后,我不刷新页面,那么它会在那一点停留,并且不会移动到第101次迭代。请帮忙!
答案 0 :(得分:1)
错误的架构。 Django和其他网络应用程序应该像这样产生线程。正确的方法是使用任务队列创建异步任务。 django最受欢迎的任务队列恰好是Celery。
然后mart:processing
页面应检查异步结果以确定任务是否已完成。草图如下:
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)