0

現在のシステムにredis キューを実装しようとしています。はjob別のモジュールに送信され、ジョブが完了して結果が返されるまで待機しjob.result、次に進みます。

with Connection(redis_connection):
    job = job_queue.enqueue(worker_func, func_input1, func_input2)

print("waiting for result")
print(datetime.datetime.now())
while job.result is None:
    pass
print(datetime.datetime.now())
print("got result")

# next step
next_step_func(job.result)

...

ここで2つの問題に直面しています:

  1. ビジー状態でwhile job.result is None、非常に長い時間がかかっています。での私の処理worker_funcは約 2 ~ 3 秒で、別のサーバーで API を呼び出す必要がありますが、ビジー状態の待機while job.result is None自体にさらに 3 秒以上かかり、合計で 5 秒以上かかります。とwhile job.result is Noneの両方のログを追加したため、 の実行後に待機が行われることは確かです。worker_funcwhile job.result is None
   2021-07-12T18:57:59.09+0800 [APP/PROC/WEB/0] OUT start work
   2021-07-12T18:57:59.09+0800 [APP/PROC/WEB/0] OUT 2021-07-12 10:57:57.601189
   2021-07-12T18:57:59.09+0800 [APP/PROC/WEB/0] OUT 2021-07-12 10:57:59.075137
   2021-07-12T18:57:59.09+0800 [APP/PROC/WEB/0] OUT end work
...
   2021-07-12T18:57:59.09+0800 [APP/PROC/WEB/0] OUT waiting for result
   2021-07-12T18:57:59.09+0800 [APP/PROC/WEB/0] OUT 2021-07-12 10:57:53.704891
   2021-07-12T18:57:59.09+0800 [APP/PROC/WEB/0] OUT 2021-07-12 10:57:59.096009

上記でわかるように、ビジー状態の待機中のループは、処理worker_funcが完了した後に発生します。

2、ビジーループの代わりに、この同期待機を実装する他のエレガントな方法はありますか? ここでのビジー ループは、多くの CPU リソースを消費するため、最適な実装ではないと思います。

ありがとう!

-- 上記のコードを編集して、より明確なコンテキストを提供します

が呼び出された場所から値をnext_step_func(job.result)返す必要があります。job_queue.enqueueしたがって、より明確な構造は次のようになります。

def endpoint():
    with Connection(redis_connection):
        job = job_queue.enqueue(worker_func, func_input1, func_input2)

    print("waiting for result")
    print(datetime.datetime.now())
    while job.result is None:
        pass
    print(datetime.datetime.now())
    print("got result")

    # next step
    return next_step_func(job.result)

...

job.resultそのため、問題は、で返されることができる必要があることですがendpoint()、ジョブ コールバックによって、ジョブが の別のコンテキストに移されon_successます。

4

1 に答える 1