diff --git a/patroni/dcs/zookeeper.py b/patroni/dcs/zookeeper.py index d7911027..fd80124e 100644 --- a/patroni/dcs/zookeeper.py +++ b/patroni/dcs/zookeeper.py @@ -1,5 +1,6 @@ import json import logging +import select import time from kazoo.client import KazooClient, KazooState, KazooRetry @@ -45,6 +46,13 @@ class PatroniSequentialThreadingHandler(SequentialThreadingHandler): args[1] = max(self._connect_timeout, args[1]/10.0) return super(PatroniSequentialThreadingHandler, self).create_connection(*args, **kwargs) + def select(self, *args, **kwargs): + """Python3 raises `ValueError` if socket is closed, because fd == -1""" + try: + return super(PatroniSequentialThreadingHandler, self).select(*args, **kwargs) + except ValueError as e: + raise select.error(9, str(e)) + class ZooKeeper(AbstractDCS): diff --git a/tests/test_zookeeper.py b/tests/test_zookeeper.py index e33047c8..cc9f396d 100644 --- a/tests/test_zookeeper.py +++ b/tests/test_zookeeper.py @@ -1,3 +1,4 @@ +import select import six import unittest @@ -115,6 +116,10 @@ class TestPatroniSequentialThreadingHandler(unittest.TestCase): self.assertIsNotNone(self.handler.create_connection((), 40)) self.assertIsNotNone(self.handler.create_connection(timeout=40)) + @patch.object(SequentialThreadingHandler, 'select', Mock(side_effect=ValueError)) + def test_select(self): + self.assertRaises(select.error, self.handler.select) + class TestZooKeeper(unittest.TestCase):