Cuando varios hilos comparten un grupo pequeño de proxies, elegir una entrada al azar puede dar el mismo proxy a dos operaciones activas. Una cola puede contener las entradas disponibles para tomar prestadas en este momento:

from contextlib import contextmanager
from queue import Queue

available = Queue()
for endpoint in dict.fromkeys(proxy_urls):
    available.put(endpoint)

@contextmanager
def borrow_proxy():
    endpoint = available.get(timeout=5)
    try:
        yield endpoint
    finally:
        available.put(endpoint)

def process_url(url):
    with borrow_proxy() as endpoint:
        return fetch_one(url, endpoint)

Construya la cola una vez, antes de iniciar los hilos de trabajo. proxy_urls contiene URL de extremo completas. Los candidatos públicos están disponibles en la lista de proxies gratuitos; use el protocolo y el formato de URL que admite fetch_one. La función fetch_one síncrona existente debe terminar su operación de red y cerrar cualquier respuesta antes de retornar. De lo contrario, el préstamo terminaría mientras la conexión aún usa ese proxy.

Queue.get elimina atómicamente una entrada disponible. Un grupo agotado espera en lugar de escanear repetidamente indicadores compartidos. Si no llega ninguna entrada en cinco segundos, queue.Empty llega al llamador; elija la política de reintento, fallo o cancelación de la aplicación para ese resultado.

El bloque finally devuelve una entrada adquirida después del éxito o de una excepción. No declara que un extremo fallido sea saludable. Las políticas de cuarentena, reemplazo y enfriamiento necesitan una ruta explícita en lugar de descartar en silencio cada proxy que ve un error temporal.

La deduplicación de cadenas de URL idénticas evita entradas duplicadas en la cola. URL distintas aún pueden referirse al mismo proxy físico o salida; agrúpelas deliberadamente si la exclusividad debe aplicarse a ese recurso compartido. La cola coordina hilos en este proceso, no trabajadores en otras máquinas.

Artículos relacionados