from typing import Optional, Union, List
[docs]class RemoteTS(object):
def __init__(
self,
host: Union[str, 'LoadBalancing', 'FaultTolerance'],
port: Optional[Union[int, str]] = None,
cep: bool = False,
):
"""
Class representing remote tick-server.
Can be :py:meth:`used <onetick.py.Session.use>`
in :py:class:`~onetick.py.Session` as well as the local databases.
Parameters
----------
host: str, :py:class:`~onetick.py.servers.LoadBalancing`, :py:class:`~onetick.py.servers.FaultTolerance`
In case of string: string with the domain name or ip-address of the remote server and,
optionally, the port number after the ``:`` character.
Otherwise, configuration of LoadBalancimg and/or FaultTolerance (please, check corresponding classes)
port: int, str, optional
The port number of the remote tick-server.
If not specified here, can be specified in the ``host`` parameter.
cep: bool
Specifies if the remote server is the CEP-mode tick-server.
Examples
--------
>>> session.use(otp.RemoteTS('server.onetick.com:50015')) # doctest: +SKIP
Combination of LoadBalancing and FaultTolerance can be used for host parameter:
>>> RemoteTS(FaultTolerance(LoadBalancing('host1:4001', 'host2:4002'),
... LoadBalancing('host3:4003', 'host3:4004')) # doctest: +SKIP
"""
if port is None:
if isinstance(host, str):
self._host, self._port = host.split(':')
else:
self._host = host
self._port = None
else:
if not isinstance(host, str):
raise ValueError(f'When port is specified, host must be string, but {type(host)} was provided')
self._host, self._port = host, port
self.cep = cep
def __repr__(self):
return self.__str__()
def __str__(self):
if isinstance(self._host, FaultTolerance) or isinstance(self._host, LoadBalancing):
return str(self._host)
return f"{self._host}:{self._port}"
[docs]class LoadBalancing(object):
def __init__(self, *sockets: str):
"""
Class representing configuration of client-side load-balancing between multiple tick servers.
Each client query selects the target tick server from the provided list according to the load-balancing policy.
Currently only `SERVER_LOAD_WEIGHTED` policy is available - tick servers are chosen at random using a weighted
probability distribution, using inverted CPU usage for weights.
LoadBalancing class is used only with :py:class:`~onetick.py.servers.RemoteTS` and
:py:class:`~onetick.py.servers.FaultTolerance`.
Parameters
----------
sockets: str
Sockets used in load-balancing configuration.
Examples
--------
>>> LoadBalancing('host1:4001', 'host2:4002', 'host3:4003') # doctest: +SKIP
"""
if len(sockets) < 2:
raise ValueError(f'There must be at least 2 sockets for load balancing but {len(sockets)} was provided')
self.sockets = sockets
def __repr__(self):
return self.__str__()
def __str__(self):
return f"({','.join(self.sockets)})"
[docs]class FaultTolerance(object):
def __init__(self, *sockets: Union[str, 'LoadBalancing']):
"""
Class representing configuration of client-side tick-server fault tolerance.
Tick servers in the fault tolerance list are selected according to their level of priority,
which is from left to right. Backup servers (servers after the first one, primary) are used only if the query
on the primary server failed or server is down. So, if the first server is down the second server is used,
if both of them are failed the third one used and so on.
FaultTolerance class is used only with :py:class:`~onetick.py.servers.RemoteTS`.
Parameters
----------
sockets: str, LoadBalancing
Sockets and/or LoadBalancing groups used in fault tolerance configuration.
Examples
--------
>>> FaultTolerance('host1:4001', 'host2:4002', 'host3:4003') # doctest: +SKIP
It is possible to have multiple load-balancing groups thus mixing together fault tolerance and load-balancing.
The selection between different load balancing groups is also done according to their priority level,
which is from left to right.
>>> FaultTolerance(LoadBalancing('host1:4001', 'host2:4002'),
... LoadBalancing('host3:4003', 'host3:4004')) # doctest: +SKIP
"""
if len(sockets) < 2:
raise ValueError(f'There must be at least 2 sockets for fault tolerance but {len(sockets)} was provided')
self.sockets = sockets
def __repr__(self):
return self.__str__()
def __str__(self):
return ','.join(map(str, self.sockets))
laser = RemoteTS("192.168.5.63", "50025")