1

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辞書内の問題ですか?

ありがとうございました。

4

2 に答える 2

3

dotCloudには、Pythonサービス用にデフォルトで4つのワーカープロセスがあります。開発サーバーをローカルで実行する場合、実行しているプロセスは1つだけです。@martijnが言ったように、あなたの問題はあなたのdictがこれらのプロセス間で共有されないという事実に関連しています。

この問題を修正するには、代わりにredisやmemcachedなどを使用してこの情報を保存できます。より長期的なストレージソリューションが必要な場合は、データベースを使用する方がおそらく適しています。

dotCloudはCPU使用率を制限しません。CPUは同じホスト上で他のCPUと共有され、バーストを許可しますが、最終的には全員が同じ量のCPUを使用します。

コードを見て、アクセスする前にdictに値があることを確認するか、データがない場合に対処するために、少なくともコードをtryexceptブロックで囲んでください。

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 
于 2012-08-17T12:06:57.087 に答える
2

おそらく dotcloud と openshift は、コードの複数のプロセスを実行します。dict はこれらのプロセス間で共有されません。

これは、追加のプロセスが追加のトレッドにアクセスできないことも意味することに注意してください。

代わりに、この種の情報には外部データベースを使用してください。このような長時間実行される非同期ジョブの場合は、別のワーカー プロセスでも実行する必要があります。たとえば、非同期ジョブ処理のオールインワン ソリューションについては、Celery を参照してください。

于 2012-08-17T10:12:00.547 に答える