Skip to content

Commit

Permalink
Merge pull request #1057 from lukebakken/pika-1055
Browse files Browse the repository at this point in the history
Heartbeats should be sent at half the specified interval
  • Loading branch information
lukebakken committed Jun 6, 2018
2 parents c0ed61e + 1b35eae commit 2a8c4ee
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 17 deletions.
13 changes: 8 additions & 5 deletions pika/heartbeat.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,24 @@ class HeartbeatChecker(object):
intervals.
"""
DEFAULT_INTERVAL = 60
MAX_IDLE_COUNT = 2

_STALE_CONNECTION = "Too Many Missed Heartbeats, No reply in %i seconds"

def __init__(self, connection, interval, idle_count=MAX_IDLE_COUNT):
def __init__(self, connection, interval=DEFAULT_INTERVAL, idle_count=MAX_IDLE_COUNT):
"""Create a heartbeat on connection sending a heartbeat frame every
interval seconds.
:param pika.connection.Connection: Connection object
:param int interval: Heartbeat check interval
:param int idle_count: Number of heartbeat intervals missed until the
connection is considered idle and disconnects
:param int interval: Heartbeat check interval. Note: heartbeats will
be sent at interval / 2 frequency.
"""
self._connection = connection
self._interval = interval
# Note: see the following document:
# https://www.rabbitmq.com/heartbeats.html#heartbeats-timeout
self._interval = float(interval / 2)
self._max_idle_count = idle_count

# Initialize counters
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/connection_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,7 @@ def test_on_connection_tune(self,
_adapter_emit_data,
method,
heartbeat_checker):
"""make sure on connection tune turns the connection params"""
"""make sure _on_connection_tune tunes the connection params"""
heartbeat_checker.return_value = 'hearbeat obj'
self.connection._flush_outbound = mock.Mock()
marshal = mock.Mock(return_value='ab')
Expand Down
26 changes: 15 additions & 11 deletions tests/unit/heartbeat_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,27 +55,31 @@ def _adapter_remove_timeout(self):

class HeartbeatTests(unittest.TestCase):

INTERVAL = 5
INTERVAL = 60
HALF_INTERVAL = INTERVAL / 2

def setUp(self):
self.mock_conn = mock.Mock(spec_set=ConstructableConnection())
self.mock_conn.bytes_received = 100
self.mock_conn.bytes_sent = 100
self.mock_conn._heartbeat_checker = mock.Mock(spec=heartbeat.HeartbeatChecker)
self.obj = heartbeat.HeartbeatChecker(self.mock_conn, self.INTERVAL)
self.obj = heartbeat.HeartbeatChecker(self.mock_conn)

def tearDown(self):
del self.obj
del self.mock_conn

def test_default_initialization_interval(self):
self.assertEqual(self.obj._interval, self.HALF_INTERVAL)

def test_default_initialization_max_idle_count(self):
self.assertEqual(self.obj._max_idle_count, self.obj.MAX_IDLE_COUNT)

def test_constructor_assignment_connection(self):
self.assertEqual(self.obj._connection, self.mock_conn)
self.assertIs(self.obj._connection, self.mock_conn)

def test_constructor_assignment_heartbeat_interval(self):
self.assertEqual(self.obj._interval, self.INTERVAL)
self.assertEqual(self.obj._interval, self.HALF_INTERVAL)

def test_constructor_initial_bytes_received(self):
self.assertEqual(self.obj._bytes_received, 0)
Expand All @@ -94,7 +98,7 @@ def test_constructor_initial_idle_byte_intervals(self):

@mock.patch('pika.heartbeat.HeartbeatChecker._setup_timer')
def test_constructor_called_setup_timer(self, timer):
heartbeat.HeartbeatChecker(self.mock_conn, self.INTERVAL)
heartbeat.HeartbeatChecker(self.mock_conn)
timer.assert_called_once_with()

def test_active_true(self):
Expand Down Expand Up @@ -122,13 +126,13 @@ def test_received(self):

@mock.patch('pika.heartbeat.HeartbeatChecker._close_connection')
def test_send_and_check_not_closed(self, close_connection):
obj = heartbeat.HeartbeatChecker(self.mock_conn, self.INTERVAL)
obj = heartbeat.HeartbeatChecker(self.mock_conn)
obj.send_and_check()
close_connection.assert_not_called()

@mock.patch('pika.heartbeat.HeartbeatChecker._close_connection')
def test_send_and_check_missed_bytes(self, close_connection):
obj = heartbeat.HeartbeatChecker(self.mock_conn, self.INTERVAL)
obj = heartbeat.HeartbeatChecker(self.mock_conn)
obj._idle_byte_intervals = self.INTERVAL
obj.send_and_check()
close_connection.assert_called_once_with()
Expand All @@ -147,19 +151,19 @@ def test_send_and_check_increment_bytes(self):

@mock.patch('pika.heartbeat.HeartbeatChecker._update_counters')
def test_send_and_check_update_counters(self, update_counters):
obj = heartbeat.HeartbeatChecker(self.mock_conn, self.INTERVAL)
obj = heartbeat.HeartbeatChecker(self.mock_conn)
obj.send_and_check()
update_counters.assert_called_once_with()

@mock.patch('pika.heartbeat.HeartbeatChecker._send_heartbeat_frame')
def test_send_and_check_send_heartbeat_frame(self, send_heartbeat_frame):
obj = heartbeat.HeartbeatChecker(self.mock_conn, self.INTERVAL)
obj = heartbeat.HeartbeatChecker(self.mock_conn)
obj.send_and_check()
send_heartbeat_frame.assert_called_once_with()

@mock.patch('pika.heartbeat.HeartbeatChecker._start_timer')
def test_send_and_check_start_timer(self, start_timer):
obj = heartbeat.HeartbeatChecker(self.mock_conn, self.INTERVAL)
obj = heartbeat.HeartbeatChecker(self.mock_conn)
obj.send_and_check()
start_timer.assert_called_once_with()

Expand Down Expand Up @@ -202,7 +206,7 @@ def test_send_heartbeat_counter_incremented(self):

def test_setup_timer_called(self):
self.mock_conn._adapter_add_timeout.assert_called_once_with(
self.INTERVAL, self.obj.send_and_check)
self.HALF_INTERVAL, self.obj.send_and_check)

@mock.patch('pika.heartbeat.HeartbeatChecker._setup_timer')
def test_start_timer_not_active(self, setup_timer):
Expand Down

0 comments on commit 2a8c4ee

Please sign in to comment.