Skip to content

Commit 44ac4f3

Browse files
authored
DRIVERS-3256 Fix PortPool uniqueness when used in multiple threads (#320)
Bump 0.11.1
1 parent fe08693 commit 44ac4f3

File tree

4 files changed

+30
-21
lines changed

4 files changed

+30
-21
lines changed

README.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,12 @@ Run a single test example for debugging with verbose and immediate stdout output
245245
Changelog
246246
---------
247247

248+
Changes in Version 0.11.1 (2025-08-27)
249+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
250+
251+
- Fix a bug where automatic port assignment would give the same port to two
252+
different mongodb servers leading to errors such as ``Found two member configurations with same host field``.
253+
248254
Changes in Version 0.11.0 (2024-12-30)
249255
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
250256

mongo_orchestration/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.12.0.dev0"
1+
__version__ = "0.11.1"

mongo_orchestration/process.py

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,10 @@ def __init__(self, min_port=1025, max_port=2000, port_sequence=None):
5353
max_port - max port number (ignoring if 'port_sequence' is not None)
5454
port_sequence - iterate sequence which contains numbers of ports
5555
"""
56-
if not self.__id: # singleton checker
57-
self.__id = id(self)
58-
self.__init_range(min_port, max_port, port_sequence)
56+
with self._lock:
57+
if not self.__id: # singleton checker
58+
self.__id = id(self)
59+
self.__init_range(min_port, max_port, port_sequence)
5960

6061
def __init_range(self, min_port=1025, max_port=2000, port_sequence=None):
6162
if port_sequence:
@@ -87,21 +88,21 @@ def release_port(self, port):
8788
def port(self, check=False):
8889
"""return next opened port
8990
Args:
90-
check - check is port realy free
91+
check - check is port really free
9192
"""
92-
if not self.__ports: # refresh ports if sequence is empty
93-
self.refresh()
93+
with self._lock:
94+
if not self.__ports: # refresh ports if sequence is empty
95+
self.refresh()
9496

95-
try:
96-
port = self.__ports.pop()
97-
if check:
98-
while not self.__check_port(port):
99-
self.release_port(port)
97+
try:
98+
while True:
10099
port = self.__ports.pop()
101-
except (IndexError, KeyError):
102-
raise IndexError("Could not find a free port,\nclosed ports: {closed}".format(closed=self.__closed))
103-
self.__closed.add(port)
104-
return port
100+
self.__closed.add(port)
101+
if check and not self.__check_port(port):
102+
continue
103+
return port
104+
except (IndexError, KeyError):
105+
raise IndexError("Could not find a free port,\nclosed ports: {closed}".format(closed=self.__closed))
105106

106107
def refresh(self, only_closed=False):
107108
"""refresh ports status

mongo_orchestration/singleton.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/python
22
# coding=utf-8
3-
# Copyright 2012-2014 MongoDB, Inc.
3+
# Copyright 2012-2025 MongoDB, Inc.
44
#
55
# Licensed under the Apache License, Version 2.0 (the "License");
66
# you may not use this file except in compliance with the License.
@@ -13,12 +13,14 @@
1313
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1414
# See the License for the specific language governing permissions and
1515
# limitations under the License.
16-
16+
import threading
1717

1818
class Singleton(object):
1919
_instances = {}
20+
_lock = threading.Lock()
2021

2122
def __new__(class_, *args, **kwargs):
22-
if class_ not in class_._instances:
23-
class_._instances[class_] = super(Singleton, class_).__new__(class_, *args, **kwargs)
24-
return class_._instances[class_]
23+
with class_._lock:
24+
if class_ not in class_._instances:
25+
class_._instances[class_] = super(Singleton, class_).__new__(class_, *args, **kwargs)
26+
return class_._instances[class_]

0 commit comments

Comments
 (0)