Skip to content

Commit 59b2752

Browse files
authored
Multi-AZ support (#308)
1 parent 8f1cb25 commit 59b2752

21 files changed

+1023
-322
lines changed

Diff for: aws_advanced_python_wrapper/aurora_connection_tracker_plugin.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,8 @@ def execute(self, target: object, method_name: str, execute_func: Callable, *arg
209209
return execute_func()
210210

211211
except Exception as e:
212-
if isinstance(e, FailoverError):
212+
# Check that e is a FailoverError and that the writer has changed
213+
if isinstance(e, FailoverError) and self._get_writer(self._plugin_service.hosts) != self._current_writer:
213214
self._tracker.invalidate_all_connections(host_info=self._current_writer)
214215
self._tracker.log_opened_connections()
215216
self._need_update_current_writer = True

Diff for: aws_advanced_python_wrapper/connection_provider.py

+27-15
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from typing import TYPE_CHECKING, Callable, Dict, Optional, Protocol, Tuple
1818

1919
if TYPE_CHECKING:
20+
from aws_advanced_python_wrapper.database_dialect import DatabaseDialect
2021
from aws_advanced_python_wrapper.driver_dialect import DriverDialect
2122
from aws_advanced_python_wrapper.hostinfo import HostInfo, HostRole
2223
from aws_advanced_python_wrapper.pep249 import Connection
@@ -38,13 +39,13 @@
3839

3940
class ConnectionProvider(Protocol):
4041

41-
def accepts_host_info(self, host_info: HostInfo, properties: Properties) -> bool:
42+
def accepts_host_info(self, host_info: HostInfo, props: Properties) -> bool:
4243
"""
4344
Indicates whether this ConnectionProvider can provide connections for the given host and
4445
properties. Some :py:class:`ConnectionProvider` implementations may not be able to handle certain connection properties.
4546
4647
:param host_info: the :py:class:`HostInfo` containing the host-port information for the host to connect to.
47-
:param properties: the connection properties.
48+
:param props: the connection properties.
4849
:return: `True` if this :py:class:`ConnectionProvider` can provide connections for the given host. `False` otherwise.
4950
"""
5051
...
@@ -59,7 +60,8 @@ def accepts_strategy(self, role: HostRole, strategy: str) -> bool:
5960
"""
6061
...
6162

62-
def get_host_info_by_strategy(self, hosts: Tuple[HostInfo, ...], role: HostRole, strategy: str, props: Optional[Properties]) -> HostInfo:
63+
def get_host_info_by_strategy(
64+
self, hosts: Tuple[HostInfo, ...], role: HostRole, strategy: str, props: Optional[Properties]) -> HostInfo:
6365
"""
6466
Return a reader or a writer host using the specified strategy.
6567
@@ -68,6 +70,7 @@ def get_host_info_by_strategy(self, hosts: Tuple[HostInfo, ...], role: HostRole,
6870
:param hosts: the list of hosts to select from.
6971
:param role: determines if the connection provider should return a reader or a writer host.
7072
:param strategy: the host selection strategy to use.
73+
:param props: the connection properties.
7174
:return: the host selected using the specified strategy.
7275
"""
7376
...
@@ -76,30 +79,34 @@ def connect(
7679
self,
7780
target_func: Callable,
7881
driver_dialect: DriverDialect,
82+
database_dialect: DatabaseDialect,
7983
host_info: HostInfo,
80-
properties: Properties) -> Connection:
84+
props: Properties) -> Connection:
8185
"""
8286
Called once per connection that needs to be created.
8387
8488
:param target_func: the `Connect` method used by target driver dialect.
8589
:param driver_dialect: a dialect that handles target driver specific implementation.
90+
:param database_dialect: a dialect that handles database engine specific implementation.
8691
:param host_info: the host details for the desired connection.
87-
:param properties: the connection properties.
92+
:param props: the connection properties.
8893
:return: the established connection resulting from the given connection information.
8994
"""
9095
...
9196

9297

9398
class DriverConnectionProvider(ConnectionProvider):
94-
_accepted_strategies: Dict[str, HostSelector] = {"random": RandomHostSelector(), "round_robin": RoundRobinHostSelector()}
99+
_accepted_strategies: Dict[str, HostSelector] = \
100+
{"random": RandomHostSelector(), "round_robin": RoundRobinHostSelector()}
95101

96-
def accepts_host_info(self, host_info: HostInfo, properties: Properties) -> bool:
102+
def accepts_host_info(self, host_info: HostInfo, props: Properties) -> bool:
97103
return True
98104

99105
def accepts_strategy(self, role: HostRole, strategy: str) -> bool:
100106
return strategy in self._accepted_strategies
101107

102-
def get_host_info_by_strategy(self, hosts: Tuple[HostInfo, ...], role: HostRole, strategy: str, props: Optional[Properties]) -> HostInfo:
108+
def get_host_info_by_strategy(
109+
self, hosts: Tuple[HostInfo, ...], role: HostRole, strategy: str, props: Optional[Properties]) -> HostInfo:
103110
host_selector: Optional[HostSelector] = self._accepted_strategies.get(strategy)
104111
if host_selector is not None:
105112
return host_selector.get_host(hosts, role, props)
@@ -111,9 +118,11 @@ def connect(
111118
self,
112119
target_func: Callable,
113120
driver_dialect: DriverDialect,
121+
database_dialect: DatabaseDialect,
114122
host_info: HostInfo,
115-
properties: Properties) -> Connection:
116-
prepared_properties = driver_dialect.prepare_connect_info(host_info, properties)
123+
props: Properties) -> Connection:
124+
prepared_properties = driver_dialect.prepare_connect_info(host_info, props)
125+
database_dialect.prepare_conn_props(prepared_properties)
117126
logger.debug("DriverConnectionProvider.ConnectingToHost", host_info.host,
118127
PropertiesUtils.log_properties(PropertiesUtils.mask_properties(prepared_properties)))
119128
return target_func(**prepared_properties)
@@ -141,23 +150,23 @@ def set_connection_provider(connection_provider: ConnectionProvider):
141150
with ConnectionProviderManager._lock:
142151
ConnectionProviderManager._conn_provider = connection_provider
143152

144-
def get_connection_provider(self, host_info: HostInfo, properties: Properties) -> ConnectionProvider:
153+
def get_connection_provider(self, host_info: HostInfo, props: Properties) -> ConnectionProvider:
145154
"""
146155
Get the :py:class:`ConnectionProvider` to use to establish a connection using the given host details and properties.
147156
If a non-default :py:class:`ConnectionProvider` has been set using :py:method:`ConnectionProvider.set_connection_provider`
148157
and :py:method:`ConnectionProvider.accepts_host_info` returns `True`, the non-default :py:class:`ConnectionProvider` will be returned.
149158
Otherwise, the default :py:class:`ConnectionProvider` will be returned.
150159
151160
:param host_info: the host info for the connection that will be established.
152-
:param properties: the connection properties.
161+
:param props: the connection properties.
153162
:return: the :py:class:`ConnectionProvider` to use to establish a connection using the given host details and properties.
154163
"""
155164
if ConnectionProviderManager._conn_provider is None:
156165
return self.default_provider
157166

158167
with ConnectionProviderManager._lock:
159168
if ConnectionProviderManager._conn_provider is not None \
160-
and ConnectionProviderManager._conn_provider.accepts_host_info(host_info, properties):
169+
and ConnectionProviderManager._conn_provider.accepts_host_info(host_info, props):
161170
return ConnectionProviderManager._conn_provider
162171

163172
return self._default_provider
@@ -180,7 +189,8 @@ def accepts_strategy(self, role: HostRole, strategy: str) -> bool:
180189

181190
return accepts_strategy
182191

183-
def get_host_info_by_strategy(self, hosts: Tuple[HostInfo, ...], role: HostRole, strategy: str, props: Optional[Properties]) -> HostInfo:
192+
def get_host_info_by_strategy(
193+
self, hosts: Tuple[HostInfo, ...], role: HostRole, strategy: str, props: Optional[Properties]) -> HostInfo:
184194
"""
185195
Return a reader or a writer host using the specified strategy.
186196
@@ -189,13 +199,15 @@ def get_host_info_by_strategy(self, hosts: Tuple[HostInfo, ...], role: HostRole,
189199
:param hosts: the list of hosts to select from.
190200
:param role: determines if the connection provider should return a reader or a writer host.
191201
:param strategy: the host selection strategy to use.
202+
:param props: the connection properties.
192203
:return: the host selected using the specified strategy.
193204
"""
194205
if ConnectionProviderManager._conn_provider is not None:
195206
with ConnectionProviderManager._lock:
196207
if ConnectionProviderManager._conn_provider is not None \
197208
and ConnectionProviderManager._conn_provider.accepts_strategy(role, strategy):
198-
return ConnectionProviderManager._conn_provider.get_host_info_by_strategy(hosts, role, strategy, props)
209+
return ConnectionProviderManager._conn_provider.get_host_info_by_strategy(
210+
hosts, role, strategy, props)
199211

200212
return self._default_provider.get_host_info_by_strategy(hosts, role, strategy, props)
201213

0 commit comments

Comments
 (0)