Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita683c65

Browse files
[Refactoring] Default port manager functions now use PortManager__Generic and LocalOperations (#251)
* [Refactoring] Default port manager functions now use PortManager__Generic and LocalOperationsThis patch deletes a duplication of port manager code.Now utils.reserve_port and utils.release_port works through _old_port_manager - it is a global instance of PortManager__Generic that uses a global instance of LocalOperations.This commit is a part of work for#247.* [BUG FIX] PortManager__ThisHost::__new__ had MT-problemAfter MT-lock we must to check __class__.sm_single_instance again.Refactoring - PortManager__ThisHost::__new__ is replaced with an explicit PortManager__ThisHost::get_single_instance() - PortManager__ThisHost::__init__ is deleted
1 parentc3b25b2 commita683c65

File tree

7 files changed

+115
-127
lines changed

7 files changed

+115
-127
lines changed

‎setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
setup(
3030
version='1.11.0',
3131
name='testgres',
32-
packages=['testgres','testgres.operations'],
32+
packages=['testgres','testgres.operations','testgres.impl'],
3333
description='Testing utility for PostgreSQL and its extensions',
3434
url='https://github.com/postgrespro/testgres',
3535
long_description=readme,
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
from ..operations.os_opsimportOsOperations
2+
3+
from ..port_managerimportPortManager
4+
from ..exceptionsimportPortForException
5+
6+
importthreading
7+
importrandom
8+
importtyping
9+
10+
11+
classPortManager__Generic(PortManager):
12+
_os_ops:OsOperations
13+
_guard:object
14+
# TODO: is there better to use bitmap fot _available_ports?
15+
_available_ports:typing.Set[int]
16+
_reserved_ports:typing.Set[int]
17+
18+
def__init__(self,os_ops:OsOperations):
19+
assertos_opsisnotNone
20+
assertisinstance(os_ops,OsOperations)
21+
self._os_ops=os_ops
22+
self._guard=threading.Lock()
23+
self._available_ports:typing.Set[int]=set(range(1024,65535))
24+
self._reserved_ports:typing.Set[int]=set()
25+
26+
defreserve_port(self)->int:
27+
assertself._guardisnotNone
28+
asserttype(self._available_ports)==set# noqa: E721t
29+
asserttype(self._reserved_ports)==set# noqa: E721
30+
31+
withself._guard:
32+
t=tuple(self._available_ports)
33+
assertlen(t)==len(self._available_ports)
34+
sampled_ports=random.sample(t,min(len(t),100))
35+
t=None
36+
37+
forportinsampled_ports:
38+
assertnot (portinself._reserved_ports)
39+
assertportinself._available_ports
40+
41+
ifnotself._os_ops.is_port_free(port):
42+
continue
43+
44+
self._reserved_ports.add(port)
45+
self._available_ports.discard(port)
46+
assertportinself._reserved_ports
47+
assertnot (portinself._available_ports)
48+
returnport
49+
50+
raisePortForException("Can't select a port.")
51+
52+
defrelease_port(self,number:int)->None:
53+
asserttype(number)==int# noqa: E721
54+
55+
assertself._guardisnotNone
56+
asserttype(self._reserved_ports)==set# noqa: E721
57+
58+
withself._guard:
59+
assertnumberinself._reserved_ports
60+
assertnot (numberinself._available_ports)
61+
self._available_ports.add(number)
62+
self._reserved_ports.discard(number)
63+
assertnot (numberinself._reserved_ports)
64+
assertnumberinself._available_ports
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from ..port_managerimportPortManager
2+
3+
from ..importutils
4+
5+
importthreading
6+
7+
8+
classPortManager__ThisHost(PortManager):
9+
sm_single_instance:PortManager=None
10+
sm_single_instance_guard=threading.Lock()
11+
12+
@staticmethod
13+
defget_single_instance()->PortManager:
14+
assert__class__==PortManager__ThisHost
15+
assert__class__.sm_single_instance_guardisnotNone
16+
17+
if__class__.sm_single_instanceisnotNone:
18+
asserttype(__class__.sm_single_instance)==__class__# noqa: E721
19+
return__class__.sm_single_instance
20+
21+
with__class__.sm_single_instance_guard:
22+
if__class__.sm_single_instanceisNone:
23+
__class__.sm_single_instance=__class__()
24+
assert__class__.sm_single_instanceisnotNone
25+
asserttype(__class__.sm_single_instance)==__class__# noqa: E721
26+
return__class__.sm_single_instance
27+
28+
defreserve_port(self)->int:
29+
returnutils.reserve_port()
30+
31+
defrelease_port(self,number:int)->None:
32+
asserttype(number)==int# noqa: E721
33+
returnutils.release_port(number)

‎testgres/node.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@
8484
InvalidOperationException
8585

8686
from .port_managerimportPortManager
87-
from .port_managerimportPortManager__ThisHost
88-
from .port_managerimportPortManager__Generic
87+
from .impl.port_manager__this_hostimportPortManager__ThisHost
88+
from .impl.port_manager__genericimportPortManager__Generic
8989

9090
from .loggerimportTestgresLogger
9191

@@ -272,7 +272,7 @@ def _get_port_manager(os_ops: OsOperations) -> PortManager:
272272
assertisinstance(os_ops,OsOperations)
273273

274274
ifisinstance(os_ops,LocalOperations):
275-
returnPortManager__ThisHost()
275+
returnPortManager__ThisHost.get_single_instance()
276276

277277
# TODO: Throw the exception "Please define a port manager." ?
278278
returnPortManager__Generic(os_ops)

‎testgres/port_manager.py

Lines changed: 0 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,3 @@
1-
from .operations.os_opsimportOsOperations
2-
3-
from .exceptionsimportPortForException
4-
5-
from .importutils
6-
7-
importthreading
8-
importrandom
9-
importtyping
10-
11-
121
classPortManager:
132
def__init__(self):
143
super().__init__()
@@ -19,85 +8,3 @@ def reserve_port(self) -> int:
198
defrelease_port(self,number:int)->None:
209
asserttype(number)==int# noqa: E721
2110
raiseNotImplementedError("PortManager::release_port is not implemented.")
22-
23-
24-
classPortManager__ThisHost(PortManager):
25-
sm_single_instance:PortManager=None
26-
sm_single_instance_guard=threading.Lock()
27-
28-
def__init__(self):
29-
pass
30-
31-
def__new__(cls)->PortManager:
32-
assert__class__==PortManager__ThisHost
33-
assert__class__.sm_single_instance_guardisnotNone
34-
35-
if__class__.sm_single_instanceisNone:
36-
with__class__.sm_single_instance_guard:
37-
__class__.sm_single_instance=super().__new__(cls)
38-
assert__class__.sm_single_instance
39-
asserttype(__class__.sm_single_instance)==__class__# noqa: E721
40-
return__class__.sm_single_instance
41-
42-
defreserve_port(self)->int:
43-
returnutils.reserve_port()
44-
45-
defrelease_port(self,number:int)->None:
46-
asserttype(number)==int# noqa: E721
47-
returnutils.release_port(number)
48-
49-
50-
classPortManager__Generic(PortManager):
51-
_os_ops:OsOperations
52-
_guard:object
53-
# TODO: is there better to use bitmap fot _available_ports?
54-
_available_ports:typing.Set[int]
55-
_reserved_ports:typing.Set[int]
56-
57-
def__init__(self,os_ops:OsOperations):
58-
assertos_opsisnotNone
59-
assertisinstance(os_ops,OsOperations)
60-
self._os_ops=os_ops
61-
self._guard=threading.Lock()
62-
self._available_ports:typing.Set[int]=set(range(1024,65535))
63-
self._reserved_ports:typing.Set[int]=set()
64-
65-
defreserve_port(self)->int:
66-
assertself._guardisnotNone
67-
asserttype(self._available_ports)==set# noqa: E721t
68-
asserttype(self._reserved_ports)==set# noqa: E721
69-
70-
withself._guard:
71-
t=tuple(self._available_ports)
72-
assertlen(t)==len(self._available_ports)
73-
sampled_ports=random.sample(t,min(len(t),100))
74-
t=None
75-
76-
forportinsampled_ports:
77-
assertnot (portinself._reserved_ports)
78-
assertportinself._available_ports
79-
80-
ifnotself._os_ops.is_port_free(port):
81-
continue
82-
83-
self._reserved_ports.add(port)
84-
self._available_ports.discard(port)
85-
assertportinself._reserved_ports
86-
assertnot (portinself._available_ports)
87-
returnport
88-
89-
raisePortForException("Can't select a port.")
90-
91-
defrelease_port(self,number:int)->None:
92-
asserttype(number)==int# noqa: E721
93-
94-
assertself._guardisnotNone
95-
asserttype(self._reserved_ports)==set# noqa: E721
96-
97-
withself._guard:
98-
assertnumberinself._reserved_ports
99-
assertnot (numberinself._available_ports)
100-
self._available_ports.add(number)
101-
self._reserved_ports.discard(number)
102-
assertnot (numberinself._reserved_ports)
103-
assertnumberinself._available_ports

‎testgres/utils.py

Lines changed: 13 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,34 @@
66
importos
77

88
importsys
9-
importsocket
10-
importrandom
119

1210
fromcontextlibimportcontextmanager
1311
frompackaging.versionimportVersion,InvalidVersion
1412
importre
1513

1614
fromsiximportiteritems
1715

18-
from .exceptionsimportPortForException
1916
from .exceptionsimportExecUtilException
2017
from .configimporttestgres_configastconf
2118
from .operations.os_opsimportOsOperations
2219
from .operations.remote_opsimportRemoteOperations
20+
from .operations.local_opsimportLocalOperations
2321
from .operations.helpersimportHelpersasOsHelpers
2422

23+
from .impl.port_manager__genericimportPortManager__Generic
24+
2525
# rows returned by PG_CONFIG
2626
_pg_config_data= {}
2727

28+
_local_operations=LocalOperations()
29+
30+
#
31+
# The old, global "port manager" always worked with LOCAL system
32+
#
33+
_old_port_manager=PortManager__Generic(_local_operations)
34+
2835
# ports used by nodes
29-
bound_ports=set()
36+
bound_ports=_old_port_manager._reserved_ports
3037

3138

3239
# re-export version type
@@ -43,28 +50,7 @@ def internal__reserve_port():
4350
"""
4451
Generate a new port and add it to 'bound_ports'.
4552
"""
46-
defLOCAL__is_port_free(port:int)->bool:
47-
"""Check if a port is free to use."""
48-
withsocket.socket(socket.AF_INET,socket.SOCK_STREAM)ass:
49-
try:
50-
s.bind(("",port))
51-
returnTrue
52-
exceptOSError:
53-
returnFalse
54-
55-
ports=set(range(1024,65535))
56-
asserttype(ports)==set# noqa: E721
57-
asserttype(bound_ports)==set# noqa: E721
58-
ports.difference_update(bound_ports)
59-
60-
sampled_ports=random.sample(tuple(ports),min(len(ports),100))
61-
62-
forportinsampled_ports:
63-
ifLOCAL__is_port_free(port):
64-
bound_ports.add(port)
65-
returnport
66-
67-
raisePortForException("Can't select a port")
53+
return_old_port_manager.reserve_port()
6854

6955

7056
definternal__release_port(port):
@@ -73,9 +59,7 @@ def internal__release_port(port):
7359
"""
7460

7561
asserttype(port)==int# noqa: E721
76-
assertportinbound_ports
77-
78-
bound_ports.discard(port)
62+
return_old_port_manager.release_port(port)
7963

8064

8165
reserve_port=internal__reserve_port

‎tests/helpers/global_data.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class OsOpsDescrs:
3939
classPortManagers:
4040
sm_remote_port_manager=PortManager__Generic(OsOpsDescrs.sm_remote_os_ops)
4141

42-
sm_local_port_manager=PortManager__ThisHost()
42+
sm_local_port_manager=PortManager__ThisHost.get_single_instance()
4343

4444
sm_local2_port_manager=PortManager__Generic(OsOpsDescrs.sm_local_os_ops)
4545

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp