Sniff based on time interval, not number of requests

This commit is contained in:
Honza Kral
2013-05-23 17:42:14 +02:00
parent 787820803a
commit c23aacf1f9
2 changed files with 21 additions and 12 deletions
+16 -10
View File
@@ -1,4 +1,5 @@
import re import re
import time
from .connection import RequestsHttpConnection from .connection import RequestsHttpConnection
from .connection_pool import ConnectionPool from .connection_pool import ConnectionPool
@@ -33,7 +34,7 @@ class Transport(object):
""" """
def __init__(self, hosts, connection_class=RequestsHttpConnection, def __init__(self, hosts, connection_class=RequestsHttpConnection,
connection_pool_class=ConnectionPool, host_info_callback=get_host_info, connection_pool_class=ConnectionPool, host_info_callback=get_host_info,
sniff_on_start=False, sniff_after_requests=None, sniff_on_start=False, sniffer_timeout=None,
sniff_on_connection_fail=False, serializer=JSONSerializer(), sniff_on_connection_fail=False, serializer=JSONSerializer(),
max_retries=3, **kwargs): max_retries=3, **kwargs):
""" """
@@ -46,7 +47,7 @@ class Transport(object):
producing a list of arguments (same as `hosts` parameter) producing a list of arguments (same as `hosts` parameter)
:arg sniff_on_start: flag indicating whether to obtain a list of nodes :arg sniff_on_start: flag indicating whether to obtain a list of nodes
from the cluser at startup time from the cluser at startup time
:arg sniff_after_requests: number of requests after which a sniffing should be initialized :arg sniffer_timeout: number of seconds between automatic sniffs
:arg sniff_on_connection_fail: flasg controlling if connection failure triggers a sniff :arg sniff_on_connection_fail: flasg controlling if connection failure triggers a sniff
:arg serializer: serializer instance :arg serializer: serializer instance
:arg max_retries: maximum number of retries before an exception is propagated :arg max_retries: maximum number of retries before an exception is propagated
@@ -73,9 +74,9 @@ class Transport(object):
self.set_connections(hosts) self.set_connections(hosts)
# sniffing data # sniffing data
self.req_counter = 0 self.sniffer_timeout = sniffer_timeout
self.sniff_after_requests = sniff_after_requests
self.sniff_on_connection_fail = sniff_on_connection_fail self.sniff_on_connection_fail = sniff_on_connection_fail
self.last_sniff = time.time()
# callback to construct host dict from data in /_cluster/nodes # callback to construct host dict from data in /_cluster/nodes
self.host_info_callback = host_info_callback self.host_info_callback = host_info_callback
@@ -116,10 +117,9 @@ class Transport(object):
:arg sniffing: flag indicating that the connection will be used for :arg sniffing: flag indicating that the connection will be used for
sniffing for nodes sniffing for nodes
""" """
if not sniffing and self.sniff_after_requests: if not sniffing and self.sniffer_timeout:
if self.req_counter >= self.sniff_after_requests: if time.time() >= self.last_sniff + self.sniffer_timeout:
self.sniff_hosts() self.sniff_hosts()
self.req_counter += 1
return self.connection_pool.get_connection() return self.connection_pool.get_connection()
def sniff_hosts(self, failure=False): def sniff_hosts(self, failure=False):
@@ -132,9 +132,15 @@ class Transport(object):
:arg failure: indicates whether this sniffing was initiated because of :arg failure: indicates whether this sniffing was initiated because of
a connection failure a connection failure
""" """
# set the counter to 0 first so that other threads won't sniff as well previous_sniff = self.last_sniff
self.req_counter = 0 try:
_, node_info = self.perform_request('GET', '/_cluster/nodes', sniffing=True) # reset last_sniff timestamp
self.last_sniff = time.time()
_, node_info = self.perform_request('GET', '/_cluster/nodes', sniffing=True)
except:
# keep the previous value on error
self.last_sniff = previous_sniff
raise
hosts = [] hosts = []
address = self.connection_class.transport_schema + '_address' address = self.connection_class.transport_schema + '_address'
+5 -2
View File
@@ -1,3 +1,4 @@
import time
from unittest import TestCase from unittest import TestCase
from elasticsearch.transport import Transport from elasticsearch.transport import Transport
@@ -91,16 +92,18 @@ class TestTransport(TestCase):
self.assertEquals(1, len(t.connection_pool.connections)) self.assertEquals(1, len(t.connection_pool.connections))
self.assertEquals('http://1.1.1.1:123', t.get_connection()[0].host) self.assertEquals('http://1.1.1.1:123', t.get_connection()[0].host)
def test_sniff_after_n_requests(self): def test_sniff_after_n_seconds(self):
t = Transport([{"data": CLUSTER_NODES}], t = Transport([{"data": CLUSTER_NODES}],
connection_class=DummyConnection, sniff_after_requests=5) connection_class=DummyConnection, sniffer_timeout=5)
for _ in range(4): for _ in range(4):
t.perform_request('GET', '/') t.perform_request('GET', '/')
self.assertEquals(1, len(t.connection_pool.connections)) self.assertEquals(1, len(t.connection_pool.connections))
self.assertIsInstance(t.get_connection()[0], DummyConnection) self.assertIsInstance(t.get_connection()[0], DummyConnection)
t.last_sniff = time.time() - 5.1
t.perform_request('GET', '/') t.perform_request('GET', '/')
self.assertEquals(1, len(t.connection_pool.connections)) self.assertEquals(1, len(t.connection_pool.connections))
self.assertEquals('http://1.1.1.1:123', t.get_connection()[0].host) self.assertEquals('http://1.1.1.1:123', t.get_connection()[0].host)
self.assertTrue(time.time() - 1 < t.last_sniff < time.time() + 0.01 )