【问题标题】:django/python : error when get value from dictionarydjango/python:从字典中获取值时出错
【发布时间】:2012-08-17 10:04:41
【问题描述】:

我在 dotcloud 和 redhat openshift 上托管了 python/django 代码。为了处理不同的用户,我使用令牌并将其保存在字典中。但是当我从dict获取值时,有时会抛出错误(键值错误)。

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 和 openshift 是否限制它们的 python cpu 使用?
  • 还是python字典里面的问题?

谢谢。

【问题讨论】:

    标签: python django dictionary dotcloud openshift


    【解决方案1】:

    dotCloud 默认有 4 个工作进程用于 python 服务。当您在本地运行开发服务器时,您只运行一个进程。就像@martijn 所说,您的问题与您的 dict 不会在这些进程之间共享这一事实有关。

    要解决此问题,您可以使用 redis 或 memcached 之类的东西来存储此信息。如果您需要更长期的存储解决方案,那么使用数据库可能更适合。

    dotCloud 不限制 CPU 使用率,CPU 在同一主机上共享,允许突发,但最终每个人都有相同数量的 CPU。

    查看您的代码,您应该在访问它之前检查以确保 dict 中有一个值,或者至少用 try except 块包围代码,以处理数据不存在的情况.

    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 
    

    【讨论】:

    • 在我的代码中,我将线程对象存储在 dict 中。我可以用 redis 来存储我的线程对象吗?
    • @alvin,如果您的线程对象可以腌制,您可以腌制它,并将其存储在 redis 中,就像您将其存储在本地字典中一样,您的密钥将与您今天使用的令牌相同,并且值将是您的腌制对象。当你需要它的时候,你把它取出来,解开它,然后你就可以像以前一样使用它了。
    【解决方案2】:

    大概 dotcloud 和 openshift 运行您的代码的多个进程; dict 不会在这些进程之间共享。

    请注意,这也意味着额外的进程也无法访问您的额外胎面。

    请改用外部数据库获取此类信息。对于像这样长时间运行的异步作业,您还需要在单独的工作进程中运行它们。例如,查看 Celery 以获得用于异步作业处理的一体化解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-08
      • 1970-01-01
      • 1970-01-01
      • 2013-07-02
      • 2013-08-27
      • 1970-01-01
      • 2015-05-23
      相关资源
      最近更新 更多