Skip to content

Commit 960faab

Browse files
author
Vedanta Jha
committed
Memcache auto discovery
1 parent 8cd0d87 commit 960faab

File tree

2 files changed

+28
-4
lines changed

2 files changed

+28
-4
lines changed

pymemcache/client/base.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1025,11 +1025,20 @@ def flush_all(self, delay: int = 0, noreply: Optional[bool] = None) -> bool:
10251025
if noreply:
10261026
cmd += b" noreply"
10271027
cmd += b"\r\n"
1028-
results = self._misc_cmd([cmd], b"flush_all", noreply)
1028+
results = self._misc_cmd([cmd], b"flush_all", noreply=False)
10291029
if noreply:
10301030
return True
10311031
return results[0] == b"OK"
10321032

1033+
def auto_discover(self):
1034+
cmd = b"config get cluster"
1035+
data = self._misc_cmd([cmd], b"config get cluster")
1036+
lines = data.split(b'\n')
1037+
configs = [conf.split(b'|') for conf in lines[2].split(b' ')]
1038+
self.quit()
1039+
nodes = [(ip, int(port)) for host, ip, port in configs]
1040+
return nodes
1041+
10331042
def quit(self) -> None:
10341043
"""
10351044
The memcached "quit" command.

pymemcache/client/hash.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,15 @@ def __init__(
4848
default_noreply=True,
4949
encoding="ascii",
5050
tls_context=None,
51+
enable_auto_discovery=False
5152
):
5253
"""
5354
Constructor.
5455
5556
Args:
5657
servers: list() of tuple(hostname, port) or string containing a UNIX
5758
socket path.
59+
If enable_auto_discovery is set, just a configuration endpoint would suffice
5860
hasher: optional class three functions ``get_node``, ``add_node``,
5961
and ``remove_node``
6062
defaults to Rendezvous (HRW) hash.
@@ -70,12 +72,14 @@ def __init__(
7072
dead_timeout (float): Time in seconds before attempting to add a node
7173
back in the pool.
7274
encoding: optional str, controls data encoding (defaults to 'ascii').
75+
enable_auto_discovery (bool): If enabled, nodes would be discovered from the configuration endpoint.
7376
7477
Further arguments are interpreted as for :py:class:`.Client`
7578
constructor.
7679
"""
7780
self.clients = {}
7881
self.retry_attempts = retry_attempts
82+
self.connect_timeout = connect_timeout
7983
self.retry_timeout = retry_timeout
8084
self.dead_timeout = dead_timeout
8185
self.use_pooling = use_pooling
@@ -112,11 +116,14 @@ def __init__(
112116
"lock_generator": lock_generator,
113117
}
114118
)
115-
116-
for server in servers:
117-
self.add_server(normalize_server_spec(server))
118119
self.encoding = encoding
119120
self.tls_context = tls_context
121+
if not isinstance(servers, list):
122+
if enable_auto_discovery:
123+
servers = self._auto_discover(server)
124+
125+
for server in servers:
126+
self.add_server(normalize_server_spec(server))
120127

121128
def _make_client_key(self, server):
122129
if isinstance(server, (list, tuple)) and len(server) == 2:
@@ -340,6 +347,14 @@ def _set_many(self, client, values, *args, **kwargs):
340347
succeeded = [key for key in values if key not in failed]
341348
return succeeded, failed, None
342349

350+
def _auto_discover(self, configuration_endpoint, tls_context):
351+
host, port = configuration_endpoint.split(':')
352+
server = (host, port)
353+
_class = PooledClient if self.use_pooling else self.client_class
354+
client = _class(server)
355+
nodes = client.auto_discover()
356+
return nodes
357+
343358
def close(self):
344359
for client in self.clients.values():
345360
self._safely_run_func(client, client.close, False)

0 commit comments

Comments
 (0)