我正在尝试使用concurrent.futures异步执行TemplateView中的某些工作单元。但是,我遇到的问题是我的异步代码没有被调用。我在这里做错了吗?这是一个只是乘以数字的示例代码,但实际上我想异步复制后台的一些文件。非常感谢任何帮助!
import concurrent.futures
import time
class AsyncTest(TemplateView):
def get(self, request, *args, **kwargs):
op = kwargs.get('op')
if op == 'asynch':
print 'using futures async'
executor = concurrent.futures.ThreadPoolExecutor(max_workers=1)
# I see this print message
print 'executing future 1 time'
executor.map(self.load, 10)
return render(request, 'text.html', {'lines':'Performing async processing!', 'op':op})
else:
return HttpResponseBadRequest("Operation not implemented at this time (op=%s)" % op)
def load(x):
#I never see this get invoked
print 'in load...sleep'
time.sleep(2)
print 'sqr x*x=%s of x=%s' %((x*x), x)
return x*x
我从未在服务器中看到任何从加载方法打印的内容,只是打印了最后一页的页面呈现:“执行未来1次”
答案 0 :(得分:0)
我放弃尝试使用并发执行非阻塞处理,因为看起来这是不可能的。我最后切换到django-celery进行异步处理。
答案 1 :(得分:0)
你怎么不努力,这是一个好主意!在这个问题上偶然发现,因为我正在寻找是否有人试过django的未来。
我必须修复你的例子来尝试它:executor.map返回一个迭代器,直到你实际迭代它才会执行。它的第二个参数必须是可迭代的,例如列表。这里可以做的是将返回的迭代器传递给模板并使用for循环实际呈现结果。
现在,芹菜是用django处理并行处理的方法,所以我同意你的第二选择。另一方面,futures
更受关注,其语法看起来更适合该特定情况。
另外,我建议另一种选择,这是我通常在页面中做的有点慢,因为它们聚合来自多个来源的信息:让视图返回一个骨架模板,可能已经显示了最有用的信息,然后使用javascript加载从其他视图加载的缺失部分。像jQuery这样的经典框架将以命令式方式帮助实现这一点,但angularjs确实值得检查其声明性方法。