02.10.01 — WebDriversPool[Driver]#
Source file:
src/ocarina/infra/drivers_pool.pyThread-safe driver pool, max concurrency enforced by semaphore, monitored async warmup, clean shutdown. No reuse — every
acquire()disposes its driver on the way out (clean state).
Constructor#
@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 | Role |
|---|---|
Queue(max_size) | Queue of pre-built available drivers. |
Semaphore(max_size) | Guarantees that at most max_size drivers live simultaneously (whether queued or acquired). |
warmup_timeout | Max no-progress delay during warmup before raising WarmupTimeoutError. Default 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 ← warmup case
└──────────────┬───────────────────┘
│ Empty
▼
┌──────────────────────────────────┐
│ sem.acquire() │ ← blocks if N drivers alive
└──────────────┬───────────────────┘
▼
┌──────────────────────────────────┐
│ create_driver() │── raises ─► sem.release(); raise
└──────────────┬───────────────────┘
▼
┌──────────────────────────────────┐
│ yield driver │ ← caller uses it
└──────────────┬───────────────────┘
▼
finally :
with suppress : dispose() ← driver disposed
sem.release() ← release a slot1. No reuse#
Queue.get_nowait() consumes the entry. Once pulled, the driver never goes back. At the end (finally), it’s disposed.