connection_pool: add health tracking and backoff
This commit is contained in:
@@ -127,11 +127,28 @@ class TorConnectionPool(object):
|
|||||||
self._warmup_connections(warmup_target)
|
self._warmup_connections(warmup_target)
|
||||||
|
|
||||||
def _warmup_connections(self, target_host, target_port=80, timeout=10):
|
def _warmup_connections(self, target_host, target_port=80, timeout=10):
|
||||||
"""Pre-warm Tor circuits by making test connections."""
|
"""Pre-warm Tor circuits by making test connections.
|
||||||
|
|
||||||
|
Makes an actual TCP connection through each Tor host to verify
|
||||||
|
end-to-end connectivity before marking the host as ready.
|
||||||
|
"""
|
||||||
_log('warming up %d tor host(s)...' % len(self.tor_hosts), 'pool')
|
_log('warming up %d tor host(s)...' % len(self.tor_hosts), 'pool')
|
||||||
warmed = 0
|
warmed = 0
|
||||||
|
|
||||||
for host_addr in self.tor_hosts:
|
for host_addr in self.tor_hosts:
|
||||||
|
# First verify we can reach the Tor SOCKS port
|
||||||
|
try:
|
||||||
|
tor_host, tor_port = host_addr.split(':')
|
||||||
|
test_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
test_sock.settimeout(5)
|
||||||
|
test_sock.connect((tor_host, int(tor_port)))
|
||||||
|
test_sock.close()
|
||||||
|
except Exception as e:
|
||||||
|
self.host_states[host_addr].record_failure()
|
||||||
|
_log('tor host %s unreachable: %s' % (host_addr, str(e)), 'error')
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Then verify we can route through Tor to an external target
|
||||||
try:
|
try:
|
||||||
start = time.time()
|
start = time.time()
|
||||||
proxy = rocksock.RocksockProxyFromURL('socks5://%s' % host_addr)
|
proxy = rocksock.RocksockProxyFromURL('socks5://%s' % host_addr)
|
||||||
@@ -145,10 +162,11 @@ class TorConnectionPool(object):
|
|||||||
sock.disconnect()
|
sock.disconnect()
|
||||||
elapsed = time.time() - start
|
elapsed = time.time() - start
|
||||||
self.host_states[host_addr].record_success(elapsed)
|
self.host_states[host_addr].record_success(elapsed)
|
||||||
|
_log('tor host %s ready (%.1fs)' % (host_addr, elapsed), 'pool')
|
||||||
warmed += 1
|
warmed += 1
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.host_states[host_addr].record_failure()
|
self.host_states[host_addr].record_failure()
|
||||||
_log('warmup failed for %s: %s' % (host_addr, str(e)), 'debug')
|
_log('tor host %s route failed: %s' % (host_addr, str(e)), 'warn')
|
||||||
|
|
||||||
self.warmup_complete = True
|
self.warmup_complete = True
|
||||||
_log('warmup complete: %d/%d hosts ready' % (warmed, len(self.tor_hosts)), 'pool')
|
_log('warmup complete: %d/%d hosts ready' % (warmed, len(self.tor_hosts)), 'pool')
|
||||||
|
|||||||
Reference in New Issue
Block a user