Skip to content

Commit e1faa38

Browse files
authored
Cache DCS instances to avoid thread leak in patronictl list -W (patroni#3205)
Close patroni#3202
1 parent 177101a commit e1faa38

File tree

2 files changed

+9
-2
lines changed

2 files changed

+9
-2
lines changed

patroni/ctl.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,10 @@ def is_citus_cluster() -> bool:
332332
return click.get_current_context().obj['__mpp'].is_enabled()
333333

334334

335+
# Cache DCS instances for given scope and group
336+
__dcs_cache: Dict[Tuple[str, Optional[int]], AbstractDCS] = {}
337+
338+
335339
def get_dcs(scope: str, group: Optional[int]) -> AbstractDCS:
336340
"""Get the DCS object.
337341
@@ -345,6 +349,8 @@ def get_dcs(scope: str, group: Optional[int]) -> AbstractDCS:
345349
:raises:
346350
:class:`PatroniCtlException`: if not suitable DCS configuration could be found.
347351
"""
352+
if (scope, group) in __dcs_cache:
353+
return __dcs_cache[(scope, group)]
348354
config = _get_configuration()
349355
config.update({'scope': scope, 'patronictl': True})
350356
if group is not None:
@@ -355,6 +361,7 @@ def get_dcs(scope: str, group: Optional[int]) -> AbstractDCS:
355361
if is_citus_cluster() and group is None:
356362
dcs.is_mpp_coordinator = lambda: True
357363
click.get_current_context().obj['__mpp'] = dcs.mpp
364+
__dcs_cache[(scope, group)] = dcs
358365
return dcs
359366
except PatroniException as e:
360367
raise PatroniCtlException(str(e))

tests/test_ctl.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,8 @@ def test_failover(self):
249249
@patch('patroni.dynamic_loader.iter_modules', Mock(return_value=['patroni.dcs.dummy', 'patroni.dcs.etcd']))
250250
def test_get_dcs(self):
251251
with click.Context(click.Command('list')) as ctx:
252-
ctx.obj = {'__config': {'dummy': {}}, '__mpp': get_mpp({})}
253-
self.assertRaises(PatroniCtlException, get_dcs, 'dummy', 0)
252+
ctx.obj = {'__config': {'dummy2': {}}, '__mpp': get_mpp({})}
253+
self.assertRaises(PatroniCtlException, get_dcs, 'dummy2', 0)
254254

255255
@patch('patroni.psycopg.connect', psycopg_connect)
256256
@patch('patroni.ctl.query_member', Mock(return_value=([['mock column']], None)))

0 commit comments

Comments
 (0)