02.10.01 — WebDriversPool[Driver]#
Fichier source :
src/ocarina/infra/drivers_pool.pyPool thread-safe de drivers, max concurrence garantie par sémaphore, warmup asynchrone surveillé, shutdown propre. Pas de réutilisation : chaque
acquire()détruit son driver à la fin (état propre).
Constructeur#
@final
class WebDriversPool[Driver]:
def __init__(
self,
create_driver: Thunk[BuiltWebDriver[Driver]],
max_size: int,
warmup_timeout: float | None = None,
) -> None:
self._create_driver = create_driver
self._pool: Queue[BuiltWebDriver[Driver]] = Queue(max_size)
self._semaphore = Semaphore(max_size)
self._warmup_timeout = (
warmup_timeout if warmup_timeout is not None and warmup_timeout > 0.1
else 60.0 * 5
)| Primitive | Rôle |
|---|---|
Queue(max_size) | File des drivers pré-créés disponibles. |
Semaphore(max_size) | Garantit que jamais plus de max_size drivers ne vivent simultanément (qu’ils soient en queue ou acquis). |
warmup_timeout | Délai max sans progression de warmup avant de lever WarmupTimeoutError. Par défaut 300s. |
acquire()#
@contextmanager
def acquire(self) -> Iterator[Driver]:
try:
driver, dispose = self._pool.get_nowait()
except Empty:
self._semaphore.acquire()
try:
driver, dispose = self._create_driver()
except Exception:
self._semaphore.release()
raise
try:
yield driver
finally:
with suppress(Exception):
dispose()
self._semaphore.release() acquire()
│
▼
┌──────────────────────────────────┐
│ pool.get_nowait() │── OK ─► driver, dispose ← cas warmup
└──────────────┬───────────────────┘
│ Empty
▼
┌──────────────────────────────────┐
│ sem.acquire() │ ← bloque si N drivers vivants
└──────────────┬───────────────────┘
▼
┌──────────────────────────────────┐
│ create_driver() │── leve ─► sem.release(); raise
└──────────────┬───────────────────┘
▼
┌──────────────────────────────────┐
│ yield driver │ ← caller utilise
└──────────────┬───────────────────┘
▼
finally :
with suppress : dispose() ← driver détruit
sem.release() ← rend une place1. Pas de réutilisation#
Queue.get_nowait() consomme l’entrée. Une fois sorti, le driver n’est jamais remis dans la queue. À la fin (finally), il est disposé.