Skip to content

Commit

Permalink
Implement reconnection strategy class
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Konstantin Belyavskiy committed Oct 3, 2018
1 parent cbb09e0 commit 495dec1
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 2 deletions.
28 changes: 26 additions & 2 deletions tarantool/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# pylint: disable=C0301,W0105,W0401,W0614

from tarantool.connection import Connection
from tarantool.mesh_connection import MeshConnection
from tarantool.const import (
SOCKET_TIMEOUT,
RECONNECT_MAX_ATTEMPTS,
Expand Down Expand Up @@ -50,5 +51,28 @@ def connect(host="localhost", port=33013, user=None, password=None,
encoding=encoding)


__all__ = ['connect', 'Connection', 'Schema', 'Error', 'DatabaseError',
'NetworkError', 'NetworkWarning', 'SchemaError']
def connectmesh(addrs=({'host': 'localhost', 'port': 3301},), user=None,
password=None, encoding=ENCODING_DEFAULT):
'''
Create a connection to the mesh of Tarantool servers.
:param list addrs: A list of maps: {'host':(HOSTNAME|IP_ADDR), 'port':PORT}.
:rtype: :class:`~tarantool.mesh_connection.MeshConnection`
:raise: `NetworkError`
'''

return MeshConnection(addrs=addrs,
user=user,
password=password,
socket_timeout=SOCKET_TIMEOUT,
reconnect_max_attempts=RECONNECT_MAX_ATTEMPTS,
reconnect_delay=RECONNECT_DELAY,
connect_now=True,
encoding=encoding)


__all__ = ['connect', 'Connection', 'connectmesh', 'MeshConnection', 'Schema',
'Error', 'DatabaseError', 'NetworkError', 'NetworkWarning',
'SchemaError']
65 changes: 65 additions & 0 deletions tarantool/mesh_connection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# -*- coding: utf-8 -*-
'''
This module provides MeshConnection class with automatic switch
between tarantool instances and basic Round-Robin strategy.
'''

from tarantool.connection import Connection
from tarantool.error import NetworkError
from tarantool.utils import ENCODING_DEFAULT
from tarantool.const import (
SOCKET_TIMEOUT,
RECONNECT_MAX_ATTEMPTS,
RECONNECT_DELAY
)


class RoundRobinStrategy(object):
def __init__(self, addrs):
self.addrs = addrs
self.pos = 0

def getnext(self):
tmp = self.pos
self.pos = (self.pos + 1) % len(self.addrs)
return self.addrs[tmp]


class MeshConnection(Connection):
def __init__(self, addrs,
user=None,
password=None,
socket_timeout=SOCKET_TIMEOUT,
reconnect_max_attempts=RECONNECT_MAX_ATTEMPTS,
reconnect_delay=RECONNECT_DELAY,
connect_now=True,
encoding=ENCODING_DEFAULT,
strategy_class=RoundRobinStrategy):
self.nattempts = 2 * len(addrs) + 1
self.strategy = strategy_class(addrs)
addr = self.strategy.getnext()
host = addr['host']
port = addr['port']
super(MeshConnection, self).__init__(host=host,
port=port,
user=user,
password=password,
socket_timeout=socket_timeout,
reconnect_max_attempts=reconnect_max_attempts,
reconnect_delay=reconnect_delay,
connect_now=connect_now,
encoding=encoding)

def _opt_reconnect(self):
nattempts = self.nattempts
while nattempts > 0:
try:
super(MeshConnection, self)._opt_reconnect()
break
except NetworkError:
nattempts -= 1
addr = self.strategy.getnext()
self.host = addr['host']
self.port = addr['port']
else:
raise NetworkError

0 comments on commit 495dec1

Please sign in to comment.