私は実際のアプリケーションで asyncio を使用しようとしていますが、それほど簡単ではありません。asyncio の専門家の助けが必要です。
イベント ループをフラッディングせずに他のタスクを生成するタスク (成功!)
いくつかの「シード」Web ページから開始して Web をクロールするようなタスクを考えてみましょう。各 Web ページは、指数関数的 (!) 進行で新しいダウンロード タスクの生成につながります。ただし、イベント ループをあふれさせたり、ネットワークを過負荷にしたりしたくはありません。タスク フローを制御したいと考えています。これは、ここで提案された素敵なマキシムのソリューションを変更してうまく達成したものです: https://mail.python.org/pipermail/python-list/2014-July/687823.html
map & reduce (失敗)
まあ、しかし、すでにpython3を使用している場合は、map()とreduce()またはfunctools.reduce()のような非常に自然なものも必要です。つまり、ページからのリンクで完了したすべてのダウンロード タスクに対して「要約」関数を呼び出す必要があります。これは私が失敗するところです:(
ユースケースをモデル化するための非常に単純化されたテストを提案したいと思います。フィボナッチ関数の実装を非効率な形で使用してみましょう。つまり、reduce() で coro_sum() を適用し、map() で適用するものを coro_fib にします。このようなもの:
@asyncio.coroutine
def coro_sum(x):
return sum(x)
@asyncio.coroutine
def coro_fib(x):
if x < 2:
return 1
res_coro =
executor_pool.spawn_task_when_arg_list_of_coros_ready(coro=coro_sum,
arg_coro_list=[coro_fib(x - 1), coro_fib(x - 2)])
return res_coro
次のテストを実行できるようにします。
1 つのワーカーで #1 をテストします。
executor_pool = ExecutorPool(workers=1)
executor_pool.as_completed( coro_fib(x) for x in range(20) )
2 つのワーカーでのテスト #2:
executor_pool = ExecutorPool(workers=2)
executor_pool.as_completed( coro_fib(x) for x in range(20) )
各 coro_fib() と coro_sum() の両方の呼び出しが、暗黙的に生成されて管理されていないだけでなく、一部のワーカーのタスクを介して行われることが非常に重要です!
この非常に自然な目標に興味を持っている asyncio の達人を見つけるのは素晴らしいことです。あなたの助けとアイデアは大歓迎です。
よろしくお願いします
ヴァレリー