Skip to content

Commit df4f545

Browse files
LocalOperations::get_single_instance is added (#252)
* LocalOperations::get_single_instance is added This patch forces testgres to use a single instance of LocalOperations that is created with default parameters. Note that, PortManager__ThisHost is used only when PostgresNode uses this single local_ops instance.
1 parent 6972bfc commit df4f545

File tree

6 files changed

+49
-11
lines changed

6 files changed

+49
-11
lines changed

testgres/cache.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,16 @@
2222
from .operations.os_ops import OsOperations
2323

2424

25-
def cached_initdb(data_dir, logfile=None, params=None, os_ops: OsOperations = LocalOperations(), bin_path=None, cached=True):
25+
def cached_initdb(data_dir, logfile=None, params=None, os_ops: OsOperations = None, bin_path=None, cached=True):
2626
"""
2727
Perform initdb or use cached node files.
2828
"""
2929

30-
assert os_ops is not None
30+
assert os_ops is None or isinstance(os_ops, OsOperations)
31+
32+
if os_ops is None:
33+
os_ops = LocalOperations.get_single_instance()
34+
3135
assert isinstance(os_ops, OsOperations)
3236

3337
def make_utility_path(name):

testgres/config.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,9 @@ class GlobalConfig(object):
5050
_cached_initdb_dir = None
5151
""" underlying class attribute for cached_initdb_dir property """
5252

53-
os_ops = LocalOperations()
53+
os_ops = LocalOperations.get_single_instance()
5454
""" OsOperation object that allows work on remote host """
55+
5556
@property
5657
def cached_initdb_dir(self):
5758
""" path to a temp directory for cached initdb. """

testgres/node.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@
9393

9494
from .standby import First
9595

96+
from . import utils
97+
9698
from .utils import \
9799
PgVer, \
98100
eprint, \
@@ -265,14 +267,17 @@ def _get_os_ops() -> OsOperations:
265267
if testgres_config.os_ops:
266268
return testgres_config.os_ops
267269

268-
return LocalOperations()
270+
return LocalOperations.get_single_instance()
269271

270272
@staticmethod
271273
def _get_port_manager(os_ops: OsOperations) -> PortManager:
272274
assert os_ops is not None
273275
assert isinstance(os_ops, OsOperations)
274276

275-
if isinstance(os_ops, LocalOperations):
277+
if os_ops is LocalOperations.get_single_instance():
278+
assert utils._old_port_manager is not None
279+
assert type(utils._old_port_manager) == PortManager__Generic # noqa: E721
280+
assert utils._old_port_manager._os_ops is os_ops
276281
return PortManager__ThisHost.get_single_instance()
277282

278283
# TODO: Throw the exception "Please define a port manager." ?
@@ -816,10 +821,13 @@ def init(self, initdb_params=None, cached=True, **kwargs):
816821
"""
817822

818823
# initialize this PostgreSQL node
824+
assert self._os_ops is not None
825+
assert isinstance(self._os_ops, OsOperations)
826+
819827
cached_initdb(
820828
data_dir=self.data_dir,
821829
logfile=self.utils_log_file,
822-
os_ops=self.os_ops,
830+
os_ops=self._os_ops,
823831
params=initdb_params,
824832
bin_path=self.bin_dir,
825833
cached=False)
@@ -2186,7 +2194,14 @@ def _escape_config_value(value):
21862194

21872195
class NodeApp:
21882196

2189-
def __init__(self, test_path=None, nodes_to_cleanup=None, os_ops=LocalOperations()):
2197+
def __init__(self, test_path=None, nodes_to_cleanup=None, os_ops=None):
2198+
assert os_ops is None or isinstance(os_ops, OsOperations)
2199+
2200+
if os_ops is None:
2201+
os_ops = LocalOperations.get_single_instance()
2202+
2203+
assert isinstance(os_ops, OsOperations)
2204+
21902205
if test_path:
21912206
if os.path.isabs(test_path):
21922207
self.test_path = test_path

testgres/operations/local_ops.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
import psutil
1212
import typing
13+
import threading
1314

1415
from ..exceptions import ExecUtilException
1516
from ..exceptions import InvalidOperationException
@@ -28,6 +29,9 @@
2829

2930

3031
class LocalOperations(OsOperations):
32+
sm_single_instance: OsOperations = None
33+
sm_single_instance_guard = threading.Lock()
34+
3135
def __init__(self, conn_params=None):
3236
if conn_params is None:
3337
conn_params = ConnectionParams()
@@ -38,6 +42,22 @@ def __init__(self, conn_params=None):
3842
self.remote = False
3943
self.username = conn_params.username or getpass.getuser()
4044

45+
@staticmethod
46+
def get_single_instance() -> OsOperations:
47+
assert __class__ == LocalOperations
48+
assert __class__.sm_single_instance_guard is not None
49+
50+
if __class__.sm_single_instance is not None:
51+
assert type(__class__.sm_single_instance) == __class__ # noqa: E721
52+
return __class__.sm_single_instance
53+
54+
with __class__.sm_single_instance_guard:
55+
if __class__.sm_single_instance is None:
56+
__class__.sm_single_instance = __class__()
57+
assert __class__.sm_single_instance is not None
58+
assert type(__class__.sm_single_instance) == __class__ # noqa: E721
59+
return __class__.sm_single_instance
60+
4161
@staticmethod
4262
def _process_output(encoding, temp_file_path):
4363
"""Process the output of a command from a temporary file."""

testgres/utils.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,10 @@
2525
# rows returned by PG_CONFIG
2626
_pg_config_data = {}
2727

28-
_local_operations = LocalOperations()
29-
3028
#
3129
# The old, global "port manager" always worked with LOCAL system
3230
#
33-
_old_port_manager = PortManager__Generic(_local_operations)
31+
_old_port_manager = PortManager__Generic(LocalOperations.get_single_instance())
3432

3533
# ports used by nodes
3634
bound_ports = _old_port_manager._reserved_ports

tests/helpers/global_data.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class OsOpsDescrs:
3131

3232
sm_remote_os_ops_descr = OsOpsDescr("remote_ops", sm_remote_os_ops)
3333

34-
sm_local_os_ops = LocalOperations()
34+
sm_local_os_ops = LocalOperations.get_single_instance()
3535

3636
sm_local_os_ops_descr = OsOpsDescr("local_ops", sm_local_os_ops)
3737

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy