2020from collections import deque
2121from collections .abc import Iterator
2222from contextlib import contextmanager
23+ from multiprocessing import Lock
2324from typing import Optional
2425
26+ lock = Lock ()
2527log = logging .getLogger (__name__ )
2628
2729# Size of the recently released ports queue
3133
3234
3335class PortManager :
34- """Thread -safe port manager to prevent EADDRINUSE errors.
36+ """Process -safe port manager to prevent EADDRINUSE errors.
3537
3638 This manager maintains a global registry of allocated ports to ensure that multiple concurrent tests don't try to
3739 use the same port. While this doesn't completely eliminate the race condition with external processes, it prevents
@@ -40,7 +42,6 @@ class PortManager:
4042 """
4143
4244 def __init__ (self ) -> None :
43- self ._lock = threading .Lock ()
4445 self ._allocated_ports : set [int ] = set ()
4546 # Recently released ports are kept in a queue to avoid immediate reuse
4647 self ._recently_released : deque [int ] = deque (maxlen = _RECENTLY_RELEASED_PORTS_MAXLEN )
@@ -61,7 +62,7 @@ def allocate_port(self, preferred_port: Optional[int] = None, max_attempts: int
6162 RuntimeError: If unable to find a free port after max_attempts
6263
6364 """
64- with self . _lock :
65+ with lock :
6566 # If a preferred port is specified and available, use it
6667 if (
6768 preferred_port is not None
@@ -113,15 +114,15 @@ def release_port(self, port: int) -> None:
113114 port: Port number to release
114115
115116 """
116- with self . _lock :
117+ with lock :
117118 if port in self ._allocated_ports :
118119 self ._allocated_ports .remove (port )
119120 # Add to the back of the queue; oldest will be evicted when queue is full
120121 self ._recently_released .append (port )
121122
122123 def release_all (self ) -> None :
123124 """Release all allocated ports."""
124- with self . _lock :
125+ with lock :
125126 self ._allocated_ports .clear ()
126127 self ._recently_released .clear ()
127128
@@ -138,7 +139,7 @@ def reserve_existing_port(self, port: int) -> bool:
138139 if port <= 0 or port > 65535 :
139140 return False
140141
141- with self . _lock :
142+ with lock :
142143 if port in self ._allocated_ports :
143144 return True
144145
0 commit comments