From 7f0043a2aab20d4de12ecfc4aa5e2b0e307f5d46 Mon Sep 17 00:00:00 2001 From: Shane Harvey Date: Wed, 27 Aug 2025 11:33:52 -0700 Subject: [PATCH 1/3] DRIVERS-3256 Make Singleton thread safe to fix PortPool uniqueness --- mongo_orchestration/singleton.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/mongo_orchestration/singleton.py b/mongo_orchestration/singleton.py index bec04be..034f1c5 100644 --- a/mongo_orchestration/singleton.py +++ b/mongo_orchestration/singleton.py @@ -1,6 +1,6 @@ #!/usr/bin/python # coding=utf-8 -# Copyright 2012-2014 MongoDB, Inc. +# Copyright 2012-2025 MongoDB, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,12 +13,14 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - +import threading class Singleton(object): _instances = {} + _lock = threading.Lock() def __new__(class_, *args, **kwargs): - if class_ not in class_._instances: - class_._instances[class_] = super(Singleton, class_).__new__(class_, *args, **kwargs) - return class_._instances[class_] + with class_._lock: + if class_ not in class_._instances: + class_._instances[class_] = super(Singleton, class_).__new__(class_, *args, **kwargs) + return class_._instances[class_] From 37a4963e197646de885ae4ae4923ed77985ea362 Mon Sep 17 00:00:00 2001 From: Shane Harvey Date: Wed, 27 Aug 2025 14:08:12 -0700 Subject: [PATCH 2/3] DRIVERS-3256 Make PortPool constructor and port() methods thread safe too --- mongo_orchestration/process.py | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/mongo_orchestration/process.py b/mongo_orchestration/process.py index d58dad8..dd7b542 100644 --- a/mongo_orchestration/process.py +++ b/mongo_orchestration/process.py @@ -53,9 +53,10 @@ def __init__(self, min_port=1025, max_port=2000, port_sequence=None): max_port - max port number (ignoring if 'port_sequence' is not None) port_sequence - iterate sequence which contains numbers of ports """ - if not self.__id: # singleton checker - self.__id = id(self) - self.__init_range(min_port, max_port, port_sequence) + with self._lock: + if not self.__id: # singleton checker + self.__id = id(self) + self.__init_range(min_port, max_port, port_sequence) def __init_range(self, min_port=1025, max_port=2000, port_sequence=None): if port_sequence: @@ -87,21 +88,21 @@ def release_port(self, port): def port(self, check=False): """return next opened port Args: - check - check is port realy free + check - check is port really free """ - if not self.__ports: # refresh ports if sequence is empty - self.refresh() + with self._lock: + if not self.__ports: # refresh ports if sequence is empty + self.refresh() - try: - port = self.__ports.pop() - if check: - while not self.__check_port(port): - self.release_port(port) + try: + while True: port = self.__ports.pop() - except (IndexError, KeyError): - raise IndexError("Could not find a free port,\nclosed ports: {closed}".format(closed=self.__closed)) - self.__closed.add(port) - return port + self.__closed.add(port) + if check and not self.__check_port(port): + continue + return port + except (IndexError, KeyError): + raise IndexError("Could not find a free port,\nclosed ports: {closed}".format(closed=self.__closed)) def refresh(self, only_closed=False): """refresh ports status From 3127b048673908ac3d1b6b30feb933f9291c0e79 Mon Sep 17 00:00:00 2001 From: Shane Harvey Date: Wed, 27 Aug 2025 14:12:40 -0700 Subject: [PATCH 3/3] DRIVERS-3256 Bump 0.11.1 --- README.rst | 6 ++++++ mongo_orchestration/_version.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 15da61a..c6f0e20 100644 --- a/README.rst +++ b/README.rst @@ -245,6 +245,12 @@ Run a single test example for debugging with verbose and immediate stdout output Changelog --------- +Changes in Version 0.11.1 (2025-08-27) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Fix a bug where automatic port assignment would give the same port to two + different mongodb servers leading to errors such as ``Found two member configurations with same host field``. + Changes in Version 0.11.0 (2024-12-30) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/mongo_orchestration/_version.py b/mongo_orchestration/_version.py index 0deb0e3..cb73775 100644 --- a/mongo_orchestration/_version.py +++ b/mongo_orchestration/_version.py @@ -1 +1 @@ -__version__ = "0.12.0.dev0" \ No newline at end of file +__version__ = "0.11.1" \ No newline at end of file