Skip to content

Commit 495dec1

Browse files
author
Konstantin Belyavskiy
committed
Implement reconnection strategy class
Extend base Connection class to support a list of nodes and an optional Strategy parameter to choose next item from this list. Add built-in reconnect strategy class based on Round-Robin alg. @params: - addrs, list of maps {'host':(HOSTNAME|IP_ADDR), 'port':PORT}. Return next connection or an error if all URIs are unavailable. Closes #106
1 parent cbb09e0 commit 495dec1

File tree

2 files changed

+91
-2
lines changed

2 files changed

+91
-2
lines changed

Diff for: tarantool/__init__.py

+26-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# pylint: disable=C0301,W0105,W0401,W0614
33

44
from tarantool.connection import Connection
5+
from tarantool.mesh_connection import MeshConnection
56
from tarantool.const import (
67
SOCKET_TIMEOUT,
78
RECONNECT_MAX_ATTEMPTS,
@@ -50,5 +51,28 @@ def connect(host="localhost", port=33013, user=None, password=None,
5051
encoding=encoding)
5152

5253

53-
__all__ = ['connect', 'Connection', 'Schema', 'Error', 'DatabaseError',
54-
'NetworkError', 'NetworkWarning', 'SchemaError']
54+
def connectmesh(addrs=({'host': 'localhost', 'port': 3301},), user=None,
55+
password=None, encoding=ENCODING_DEFAULT):
56+
'''
57+
Create a connection to the mesh of Tarantool servers.
58+
59+
:param list addrs: A list of maps: {'host':(HOSTNAME|IP_ADDR), 'port':PORT}.
60+
61+
:rtype: :class:`~tarantool.mesh_connection.MeshConnection`
62+
63+
:raise: `NetworkError`
64+
'''
65+
66+
return MeshConnection(addrs=addrs,
67+
user=user,
68+
password=password,
69+
socket_timeout=SOCKET_TIMEOUT,
70+
reconnect_max_attempts=RECONNECT_MAX_ATTEMPTS,
71+
reconnect_delay=RECONNECT_DELAY,
72+
connect_now=True,
73+
encoding=encoding)
74+
75+
76+
__all__ = ['connect', 'Connection', 'connectmesh', 'MeshConnection', 'Schema',
77+
'Error', 'DatabaseError', 'NetworkError', 'NetworkWarning',
78+
'SchemaError']

Diff for: tarantool/mesh_connection.py

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# -*- coding: utf-8 -*-
2+
'''
3+
This module provides MeshConnection class with automatic switch
4+
between tarantool instances and basic Round-Robin strategy.
5+
'''
6+
7+
from tarantool.connection import Connection
8+
from tarantool.error import NetworkError
9+
from tarantool.utils import ENCODING_DEFAULT
10+
from tarantool.const import (
11+
SOCKET_TIMEOUT,
12+
RECONNECT_MAX_ATTEMPTS,
13+
RECONNECT_DELAY
14+
)
15+
16+
17+
class RoundRobinStrategy(object):
18+
def __init__(self, addrs):
19+
self.addrs = addrs
20+
self.pos = 0
21+
22+
def getnext(self):
23+
tmp = self.pos
24+
self.pos = (self.pos + 1) % len(self.addrs)
25+
return self.addrs[tmp]
26+
27+
28+
class MeshConnection(Connection):
29+
def __init__(self, addrs,
30+
user=None,
31+
password=None,
32+
socket_timeout=SOCKET_TIMEOUT,
33+
reconnect_max_attempts=RECONNECT_MAX_ATTEMPTS,
34+
reconnect_delay=RECONNECT_DELAY,
35+
connect_now=True,
36+
encoding=ENCODING_DEFAULT,
37+
strategy_class=RoundRobinStrategy):
38+
self.nattempts = 2 * len(addrs) + 1
39+
self.strategy = strategy_class(addrs)
40+
addr = self.strategy.getnext()
41+
host = addr['host']
42+
port = addr['port']
43+
super(MeshConnection, self).__init__(host=host,
44+
port=port,
45+
user=user,
46+
password=password,
47+
socket_timeout=socket_timeout,
48+
reconnect_max_attempts=reconnect_max_attempts,
49+
reconnect_delay=reconnect_delay,
50+
connect_now=connect_now,
51+
encoding=encoding)
52+
53+
def _opt_reconnect(self):
54+
nattempts = self.nattempts
55+
while nattempts > 0:
56+
try:
57+
super(MeshConnection, self)._opt_reconnect()
58+
break
59+
except NetworkError:
60+
nattempts -= 1
61+
addr = self.strategy.getnext()
62+
self.host = addr['host']
63+
self.port = addr['port']
64+
else:
65+
raise NetworkError

0 commit comments

Comments
 (0)