Skip to content

Commit

Permalink
⚡ Improved reliability with PoliceTraffic.borrow with type as indicat…
Browse files Browse the repository at this point in the history
…or when heavily accessed by many threads (#86)
  • Loading branch information
Ousret authored Feb 21, 2024
1 parent 8c6ff60 commit 1378e51
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 7 deletions.
5 changes: 5 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
2.5.904 (2024-02-21)
====================

- Improved reliability with PoliceTraffic.borrow with type as indicator when heavily accessed by many threads.

2.5.903 (2024-02-20)
====================

Expand Down
2 changes: 1 addition & 1 deletion src/urllib3/_version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# This file is protected via CODEOWNERS
from __future__ import annotations

__version__ = "2.5.903"
__version__ = "2.5.904"
35 changes: 29 additions & 6 deletions src/urllib3/util/traffic_police.py
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ def forget(self, traffic_indicator: MappableTraffic) -> None:

def locate(
self,
traffic_indicator: MappableTraffic | type,
traffic_indicator: MappableTraffic,
block: bool = True,
timeout: float | None = None,
) -> T | None:
Expand All @@ -426,8 +426,7 @@ def locate(
conn_or_pool = self._map[key]
obj_id = id(conn_or_pool)
else:
conn_or_pool = self._find_by(traffic_indicator)
obj_id = id(conn_or_pool) if conn_or_pool is not None else None
raise ValueError("unsupported traffic_indicator")

if conn_or_pool is None and obj_id is None:
with self._lock:
Expand Down Expand Up @@ -488,9 +487,33 @@ def borrow(
) -> typing.Generator[T, None, None]:
try:
if traffic_indicator:
conn_or_pool = self.locate(
traffic_indicator, block=block, timeout=timeout
)
if isinstance(traffic_indicator, type):
with self._map_lock:
with self._lock:
conn_or_pool = self._find_by(traffic_indicator)

if conn_or_pool:
obj_id = id(conn_or_pool)

if self.busy:
(
cursor_obj_id,
cursor_conn_or_pool,
) = self._local.cursor

if cursor_obj_id != obj_id:
raise AtomicTraffic(
"Seeking to locate a connection when having another one used, did you forget a call to release?"
)

if self.concurrency is False:
self._container.pop(obj_id)

self._local.cursor = (obj_id, conn_or_pool)
else:
conn_or_pool = self.locate(
traffic_indicator, block=block, timeout=timeout
)
else:
# simulate reentrant lock/borrow
# get_response PM -> get_response HPM -> read R
Expand Down

0 comments on commit 1378e51

Please sign in to comment.