固定プールなら、ラウンドロビン選択は驚くほど短く書けます。

from itertools import cycle

choices = cycle([
    "http://proxy-a.example:8080",
    "http://proxy-b.example:8080",
    "http://proxy-c.example:8080",
])

endpoint = next(choices)

サンプルの URL は、自社サービスや HTTP プロキシ一覧 にある HTTP エンドポイントに置き換えてください。呼び出すたびに A、B、C、そして再び A が返ります。選んだ値は、続くリクエストを設定するときに使います。リクエストごとにイテレータを作り直すと順序が最初に戻ります。Requests では、選んだエンドポイントをリクエストに渡します。

リストを使いたい場合は、先頭の要素を末尾へ移します。pool.append(pool.pop()) は最後の要素を取り出してそのまま戻すので、先頭の要素は決して変わりません。キューの操作は pool.append(pool.pop(0)) ですが、先頭から取り除くと残りのリスト要素がずれます。

このイテレータの役割は意図的に控えめです。可用性を確認せず、失敗したエントリを削除せず、別の外向き出口も保証しません。複数のエンドポイントが同じ外向きアドレスを共有することがあります。

再試行ポリシーとプールの更新は、この小さなセレクタの外に置いてください。共有イテレータには 並行コードでの意図的な所有モデル も必要で、選ばれたエンドポイントがそれを受け取った処理に結び付いたままになります。

関連記事