简体   繁体   English

django / python:从字典获取值时出错

[英]django/python : error when get value from dictionary

I have python/django code hosted at dotcloud and redhat openshift. 我在dotcloud和redhat openshift上托管了python / django代码。 For handling different user, I use token and save it in dictionary. 为了处理不同的用户,我使用令牌并将其保存在字典中。 But when I get the value from dict, it sometimes throws an error(key value error). 但是当我从字典中获取值时,有时会抛出错误(键值错误)。

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 })

The code below is executed in 1 second intervals via javascript xmlhttprequest to server. 以下代码通过javascript xmlhttprequest发送到服务器,每隔1秒执行一次。 It will check variable inside another thread and return the value to user page. 它将检查另一个线程中的变量,并将该值返回到用户页面。

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))

After testing for several days, it sometimes return : 经过几天的测试,有时会返回:

thread_queue = {}

It sometimes succeeds : 有时会成功:

thread_queue = {'wFVdMDF9a2qSQCAXi7za': , 'EVukb7QdNdDgCf2ZtVSw': , 'C7pkqYRvRadTfEce5j2b': , '2xPFhR6wm9bs9BEQNfdd': } 

I never get this result when I'm running django locally via manage.py runserver, and accessing it with google chrome, but when I upload it to dotcloud or openshift, it always gives the above problem. 当我通过manage.py runserver在本地运行django并使用google chrome访问它时,我从未得到此结果,但是当我将其上传到dotcloud或openshift时,它总是会出现上述问题。 My question : 我的问题 :

  • How can I solve this problem ? 我怎么解决这个问题 ?
  • Does dotcloud and openshift limit their python cpu usage ? dotcloud和openshift会限制其python cpu使用吗?
  • Or is the problem inside the python dictionary ? 还是python字典内部的问题?

Thank You. 谢谢。

dotCloud has 4 worker processes by default for the python service. dotCloud默认为python服务提供4个工作进程。 When you run the dev server locally, you are only running one process. 在本地运行开发服务器时,仅运行一个进程。 Like @martijn said, your issue is related to the fact that your dict isn't going to be shared between these processes. 就像@martijn所说的那样,您的问题与以下事实有关:您的命令将不会在这些进程之间共享。

To fix this issue, you could use something like redis or memcached to store this information instead. 要解决此问题,您可以使用redis或memcached之类的方法来存储此信息。 If you need a more long term storage solution, then using a database is probably better suited. 如果您需要更长期的存储解决方案,那么使用数据库可能更合适。

dotCloud does not limit the CPU usage, The CPU is shared amongst others on the same host, and allows bursting, but in the end everyone has the same amount of CPU. dotCloud并不限制CPU使用率,CPU在同一主机上共享,并且允许突发,但最终每个人都拥有相同数量的CPU。

Looking at your code, you should check to make sure there is a value in the dict before you access it, or at a minimum surround the code with a try except block, to handle the case when the data isn't there. 查看您的代码,您应该在访问字典之前检查并确保该字典中有一个值,或者至少在代码中用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 

Presumably dotcloud and openshift run multiple processes of your code; 大概dotcloud和openshift运行代码的多个过程; the dict is not going to be shared between these processes. dict将不会在这些进程之间共享。

Note that that also means the extra processes will not have access to your extra tread either. 请注意,这也意味着额外的进程也将无法访问您的额外权限。

Use an external database for this kind of information instead. 请使用外部数据库获取此类信息。 For long-running asynchronous jobs like these you also need to run them in a separate worker process. 对于此类长期运行的异步作业,您还需要在单独的工作进程中运行它们。 Look at Celery for an all-in-one solution for asynchronous job handling, for example. 例如,请参见Celery,了解用于异步作业处理的多合一解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM