Skip to content

Commit a4ef623

Browse files
authored
Merge pull request #372 from toddpalino/master
Fully resolve and randomize the client host list at connect time
2 parents e7d60ab + 78ddc48 commit a4ef623

5 files changed

Lines changed: 42 additions & 11 deletions

File tree

CHANGES.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,19 @@
11
Changelog
22
=========
33

4+
2.X.Y (TBD)
5+
-----------
6+
7+
Features
8+
********
9+
10+
Bug Handling
11+
************
12+
- #372: fully resolve multiple records for hosts in the zookeeper connection string
13+
14+
Documentation
15+
*************
16+
417
2.2.1 (2015-06-17)
518
------------------
619

ensure-zookeeper-env.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ HERE=`pwd`
66
ZOO_BASE_DIR="$HERE/zookeeper"
77
ZOOKEEPER_VERSION=${ZOOKEEPER_VERSION:-3.4.6}
88
ZOOKEEPER_PATH="$ZOO_BASE_DIR/$ZOOKEEPER_VERSION"
9-
ZOO_MIRROR_URL="http://apache.osuosl.org/"
9+
ZOO_MIRROR_URL="http://archive.apache.org/dist"
1010

1111

1212
function download_zookeeper(){

kazoo/client.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -366,10 +366,12 @@ def set_hosts(self, hosts, randomize_hosts=None):
366366
367367
"""
368368

369-
if randomize_hosts is None:
370-
randomize_hosts = self.randomize_hosts
369+
# Change the client setting for randomization if specified
370+
if randomize_hosts is not None:
371+
self.randomize_hosts = randomize_hosts
371372

372-
self.hosts, chroot = collect_hosts(hosts, randomize_hosts)
373+
# Randomizing the list will be done at connect time
374+
self.hosts, chroot = collect_hosts(hosts)
373375

374376
if chroot:
375377
new_chroot = normpath(chroot)

kazoo/hosts.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
import random
2-
31
from six.moves import urllib_parse
42

53

6-
def collect_hosts(hosts, randomize=True):
4+
def collect_hosts(hosts):
75
"""Collect a set of hosts and an optional chroot from a string."""
86
host_ports, chroot = hosts.partition("/")[::2]
97
chroot = "/" + chroot if chroot else None
@@ -19,7 +17,4 @@ def collect_hosts(hosts, randomize=True):
1917
port = int(res.port) if res.port else 2181
2018
result.append((host.strip(), port))
2119

22-
if randomize:
23-
random.shuffle(result)
24-
2520
return result, chroot

kazoo/protocol/connection.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -478,10 +478,31 @@ def zk_loop(self):
478478
self.client._session_callback(KeeperState.CLOSED)
479479
self.logger.log(BLATHER, 'Connection stopped')
480480

481+
def _expand_client_hosts(self):
482+
# Expand the entire list in advance so we can randomize it if needed
483+
host_ports = []
484+
for host, port in self.client.hosts:
485+
try:
486+
for rhost in socket.getaddrinfo(host.strip(), port, 0, 0, socket.IPPROTO_TCP):
487+
host_ports.append((rhost[4][0], rhost[4][1]))
488+
except socket.gaierror as e:
489+
# Skip hosts that don't resolve
490+
self.logger.warning("Cannot resolve %s: %s", host.strip(), e)
491+
pass
492+
if self.client.randomize_hosts:
493+
random.shuffle(host_ports)
494+
return host_ports
495+
481496
def _connect_loop(self, retry):
482497
# Iterate through the hosts a full cycle before starting over
483498
status = None
484-
for host, port in self.client.hosts:
499+
host_ports = self._expand_client_hosts()
500+
501+
# Check for an empty hostlist, indicating none resolved
502+
if len(host_ports) == 0:
503+
return STOP_CONNECTING
504+
505+
for host, port in host_ports:
485506
if self.client._stopped.is_set():
486507
status = STOP_CONNECTING
487508
break

0 commit comments

Comments
 (0)