| | from __future__ import annotations |
| |
|
| | import threading |
| |
|
| |
|
| | class _HTTP2ProbeCache: |
| | __slots__ = ( |
| | "_lock", |
| | "_cache_locks", |
| | "_cache_values", |
| | ) |
| |
|
| | def __init__(self) -> None: |
| | self._lock = threading.Lock() |
| | self._cache_locks: dict[tuple[str, int], threading.RLock] = {} |
| | self._cache_values: dict[tuple[str, int], bool | None] = {} |
| |
|
| | def acquire_and_get(self, host: str, port: int) -> bool | None: |
| | |
| | |
| | value = None |
| | with self._lock: |
| | key = (host, port) |
| | try: |
| | value = self._cache_values[key] |
| | |
| | if value is not None: |
| | return value |
| | except KeyError: |
| | self._cache_locks[key] = threading.RLock() |
| | self._cache_values[key] = None |
| |
|
| | |
| | |
| | |
| | key_lock = self._cache_locks[key] |
| | key_lock.acquire() |
| | try: |
| | |
| | |
| | value = self._cache_values[key] |
| |
|
| | |
| | except BaseException as e: |
| | assert not isinstance(e, KeyError) |
| | key_lock.release() |
| | raise |
| |
|
| | return value |
| |
|
| | def set_and_release( |
| | self, host: str, port: int, supports_http2: bool | None |
| | ) -> None: |
| | key = (host, port) |
| | key_lock = self._cache_locks[key] |
| | with key_lock: |
| | if supports_http2 is None and self._cache_values[key] is not None: |
| | raise ValueError( |
| | "Cannot reset HTTP/2 support for origin after value has been set." |
| | ) |
| |
|
| | self._cache_values[key] = supports_http2 |
| | key_lock.release() |
| |
|
| | def _values(self) -> dict[tuple[str, int], bool | None]: |
| | """This function is for testing purposes only. Gets the current state of the probe cache""" |
| | with self._lock: |
| | return {k: v for k, v in self._cache_values.items()} |
| |
|
| | def _reset(self) -> None: |
| | """This function is for testing purposes only. Reset the cache values""" |
| | with self._lock: |
| | self._cache_locks = {} |
| | self._cache_values = {} |
| |
|
| |
|
| | _HTTP2_PROBE_CACHE = _HTTP2ProbeCache() |
| |
|
| | set_and_release = _HTTP2_PROBE_CACHE.set_and_release |
| | acquire_and_get = _HTTP2_PROBE_CACHE.acquire_and_get |
| | _values = _HTTP2_PROBE_CACHE._values |
| | _reset = _HTTP2_PROBE_CACHE._reset |
| |
|
| | __all__ = [ |
| | "set_and_release", |
| | "acquire_and_get", |
| | ] |
| |
|