[英]django/python : error when get value from dictionary
我在dotcloud和redhat openshift上托管了python / django代码。 为了处理不同的用户,我使用令牌并将其保存在字典中。 但是当我从字典中获取值时,有时会抛出错误(键值错误)。
import threading
thread_queue = {}
def download(request):
dl_val = request.POST["input1"]
client_token = str(request.POST["pagecookie"])
# save client token as keys and thread object as value in dictionary
thread_queue[client_token] = DownloadThread(dl_val,client_token)
thread_queue[client_token].start()
return render_to_response("progress.html",
{ "dl_val" : dl_val, "token" : client_token })
以下代码通过javascript xmlhttprequest发送到服务器,每隔1秒执行一次。 它将检查另一个线程中的变量,并将该值返回到用户页面。
def downloadProgress(request, token):
# sometimes i use this for check the content of dict
#resp = HttpResponse("thread_queue = "+str(thread_queue))
#return resp
prog, total = thread_queue[str(token)].getValue() # problematic line !
if prog == 0:
# prevent division by zero
return HttpResponse("0")
percent = float(prog) / float(total)
percent = round(percent*100, 2)
if percent >= 100:
try:
f_name = thread_queue[token].getFileName()[1]
except:
downloadProgress(request,token)
resp = HttpResponse('<a href="http://'+request.META['HTTP_HOST']+
'/dl/'+token+'/">'+f_name+'</a><br />')
return resp
else:
return HttpResponse(str(percent))
经过几天的测试,有时会返回:
thread_queue = {}
有时会成功:
thread_queue = {'wFVdMDF9a2qSQCAXi7za': , 'EVukb7QdNdDgCf2ZtVSw': , 'C7pkqYRvRadTfEce5j2b': , '2xPFhR6wm9bs9BEQNfdd': }
当我通过manage.py runserver在本地运行django并使用google chrome访问它时,我从未得到此结果,但是当我将其上传到dotcloud或openshift时,它总是会出现上述问题。 我的问题 :
谢谢。
dotCloud默认为python服务提供4个工作进程。 在本地运行开发服务器时,仅运行一个进程。 就像@martijn所说的那样,您的问题与以下事实有关:您的命令将不会在这些进程之间共享。
要解决此问题,您可以使用redis或memcached之类的方法来存储此信息。 如果您需要更长期的存储解决方案,那么使用数据库可能更合适。
dotCloud并不限制CPU使用率,CPU在同一主机上共享,并且允许突发,但最终每个人都拥有相同数量的CPU。
查看您的代码,您应该在访问字典之前检查并确保该字典中有一个值,或者至少在代码中用try try块包围,以处理数据不存在的情况。
str_token = str(token)
if str_token in thread_queue:
prog, total = thread_queue[str_token].getValue() # problematic line !
else:
# value isn't there, do something else
大概dotcloud和openshift运行代码的多个过程; dict将不会在这些进程之间共享。
请注意,这也意味着额外的进程也将无法访问您的额外权限。
请使用外部数据库获取此类信息。 对于此类长期运行的异步作业,您还需要在单独的工作进程中运行它们。 例如,请参见Celery,了解用于异步作业处理的多合一解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.