Skip to content

Commit 866003b

Browse files
authored
Extract additional interfaces and abstract classes (#3754)
1 parent f9fdc99 commit 866003b

File tree

13 files changed

+225
-209
lines changed

13 files changed

+225
-209
lines changed

redis/multidb/circuit.py

Lines changed: 46 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,57 @@ def database(self, database):
4545
"""Set database associated with this circuit."""
4646
pass
4747

48+
class BaseCircuitBreaker(CircuitBreaker):
49+
"""
50+
Base implementation of Circuit Breaker interface.
51+
"""
52+
def __init__(self, cb: pybreaker.CircuitBreaker):
53+
self._cb = cb
54+
self._state_pb_mapper = {
55+
State.CLOSED: self._cb.close,
56+
State.OPEN: self._cb.open,
57+
State.HALF_OPEN: self._cb.half_open,
58+
}
59+
self._database = None
60+
61+
@property
62+
def grace_period(self) -> float:
63+
return self._cb.reset_timeout
64+
65+
@grace_period.setter
66+
def grace_period(self, grace_period: float):
67+
self._cb.reset_timeout = grace_period
68+
69+
@property
70+
def state(self) -> State:
71+
return State(value=self._cb.state.name)
72+
73+
@state.setter
74+
def state(self, state: State):
75+
self._state_pb_mapper[state]()
76+
77+
@property
78+
def database(self):
79+
return self._database
80+
81+
@database.setter
82+
def database(self, database):
83+
self._database = database
84+
85+
class SyncCircuitBreaker(CircuitBreaker):
86+
"""
87+
Synchronous implementation of Circuit Breaker interface.
88+
"""
4889
@abstractmethod
49-
def on_state_changed(self, cb: Callable[["CircuitBreaker", State, State], None]):
90+
def on_state_changed(self, cb: Callable[["SyncCircuitBreaker", State, State], None]):
5091
"""Callback called when the state of the circuit changes."""
5192
pass
5293

5394
class PBListener(pybreaker.CircuitBreakerListener):
5495
"""Wrapper for callback to be compatible with pybreaker implementation."""
5596
def __init__(
5697
self,
57-
cb: Callable[[CircuitBreaker, State, State], None],
98+
cb: Callable[[SyncCircuitBreaker, State, State], None],
5899
database,
59100
):
60101
"""
@@ -75,8 +116,7 @@ def state_change(self, cb, old_state, new_state):
75116
new_state = State(value=new_state.name)
76117
self._cb(cb, old_state, new_state)
77118

78-
79-
class PBCircuitBreakerAdapter(CircuitBreaker):
119+
class PBCircuitBreakerAdapter(SyncCircuitBreaker, BaseCircuitBreaker):
80120
def __init__(self, cb: pybreaker.CircuitBreaker):
81121
"""
82122
Initialize a PBCircuitBreakerAdapter instance.
@@ -87,38 +127,8 @@ def __init__(self, cb: pybreaker.CircuitBreaker):
87127
Args:
88128
cb: A pybreaker CircuitBreaker instance to be adapted.
89129
"""
90-
self._cb = cb
91-
self._state_pb_mapper = {
92-
State.CLOSED: self._cb.close,
93-
State.OPEN: self._cb.open,
94-
State.HALF_OPEN: self._cb.half_open,
95-
}
96-
self._database = None
97-
98-
@property
99-
def grace_period(self) -> float:
100-
return self._cb.reset_timeout
101-
102-
@grace_period.setter
103-
def grace_period(self, grace_period: float):
104-
self._cb.reset_timeout = grace_period
105-
106-
@property
107-
def state(self) -> State:
108-
return State(value=self._cb.state.name)
109-
110-
@state.setter
111-
def state(self, state: State):
112-
self._state_pb_mapper[state]()
113-
114-
@property
115-
def database(self):
116-
return self._database
117-
118-
@database.setter
119-
def database(self, database):
120-
self._database = database
130+
super().__init__(cb)
121131

122-
def on_state_changed(self, cb: Callable[["CircuitBreaker", State, State], None]):
132+
def on_state_changed(self, cb: Callable[["SyncCircuitBreaker", State, State], None]):
123133
listener = PBListener(cb, self.database)
124134
self._cb.add_listener(listener)

redis/multidb/client.py

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
import threading
2-
import socket
32
from typing import List, Any, Callable, Optional
43

54
from redis.background import BackgroundScheduler
6-
from redis.client import PubSubWorkerThread
7-
from redis.exceptions import ConnectionError, TimeoutError
85
from redis.commands import RedisModuleCommands, CoreCommands
96
from redis.multidb.command_executor import DefaultCommandExecutor
107
from redis.multidb.config import MultiDbConfig, DEFAULT_GRACE_PERIOD
11-
from redis.multidb.circuit import State as CBState, CircuitBreaker
12-
from redis.multidb.database import Database, AbstractDatabase, Databases
8+
from redis.multidb.circuit import State as CBState, SyncCircuitBreaker
9+
from redis.multidb.database import Database, Databases, SyncDatabase
1310
from redis.multidb.exception import NoValidDatabaseException
1411
from redis.multidb.failure_detector import FailureDetector
1512
from redis.multidb.healthcheck import HealthCheck
@@ -92,7 +89,7 @@ def get_databases(self) -> Databases:
9289
"""
9390
return self._databases
9491

95-
def set_active_database(self, database: AbstractDatabase) -> None:
92+
def set_active_database(self, database: SyncDatabase) -> None:
9693
"""
9794
Promote one of the existing databases to become an active.
9895
"""
@@ -115,7 +112,7 @@ def set_active_database(self, database: AbstractDatabase) -> None:
115112

116113
raise NoValidDatabaseException('Cannot set active database, database is unhealthy')
117114

118-
def add_database(self, database: AbstractDatabase):
115+
def add_database(self, database: SyncDatabase):
119116
"""
120117
Adds a new database to the database list.
121118
"""
@@ -129,7 +126,7 @@ def add_database(self, database: AbstractDatabase):
129126
self._databases.add(database, database.weight)
130127
self._change_active_database(database, highest_weighted_db)
131128

132-
def _change_active_database(self, new_database: AbstractDatabase, highest_weight_database: AbstractDatabase):
129+
def _change_active_database(self, new_database: SyncDatabase, highest_weight_database: SyncDatabase):
133130
if new_database.weight > highest_weight_database.weight and new_database.circuit.state == CBState.CLOSED:
134131
self.command_executor.active_database = new_database
135132

@@ -143,7 +140,7 @@ def remove_database(self, database: Database):
143140
if highest_weight <= weight and highest_weighted_db.circuit.state == CBState.CLOSED:
144141
self.command_executor.active_database = highest_weighted_db
145142

146-
def update_database_weight(self, database: AbstractDatabase, weight: float):
143+
def update_database_weight(self, database: SyncDatabase, weight: float):
147144
"""
148145
Updates a database from the database list.
149146
"""
@@ -210,7 +207,7 @@ def pubsub(self, **kwargs):
210207

211208
return PubSub(self, **kwargs)
212209

213-
def _check_db_health(self, database: AbstractDatabase, on_error: Callable[[Exception], None] = None) -> None:
210+
def _check_db_health(self, database: SyncDatabase, on_error: Callable[[Exception], None] = None) -> None:
214211
"""
215212
Runs health checks on the given database until first failure.
216213
"""
@@ -247,15 +244,15 @@ def _check_databases_health(self, on_error: Callable[[Exception], None] = None):
247244
for database, _ in self._databases:
248245
self._check_db_health(database, on_error)
249246

250-
def _on_circuit_state_change_callback(self, circuit: CircuitBreaker, old_state: CBState, new_state: CBState):
247+
def _on_circuit_state_change_callback(self, circuit: SyncCircuitBreaker, old_state: CBState, new_state: CBState):
251248
if new_state == CBState.HALF_OPEN:
252249
self._check_db_health(circuit.database)
253250
return
254251

255252
if old_state == CBState.CLOSED and new_state == CBState.OPEN:
256253
self._bg_scheduler.run_once(DEFAULT_GRACE_PERIOD, _half_open_circuit, circuit)
257254

258-
def _half_open_circuit(circuit: CircuitBreaker):
255+
def _half_open_circuit(circuit: SyncCircuitBreaker):
259256
circuit.state = CBState.HALF_OPEN
260257

261258

@@ -450,8 +447,8 @@ def run_in_thread(
450447
exception_handler: Optional[Callable] = None,
451448
sharded_pubsub: bool = False,
452449
) -> "PubSubWorkerThread":
453-
return self._client.command_executor.execute_pubsub_run_in_thread(
454-
sleep_time=sleep_time,
450+
return self._client.command_executor.execute_pubsub_run(
451+
sleep_time,
455452
daemon=daemon,
456453
exception_handler=exception_handler,
457454
pubsub=self,

0 commit comments

Comments
 (0)