Skip to content

Commit 54d51df

Browse files
authored
Merge branch 'master' into stale-issues-management
2 parents bd91832 + 2a46432 commit 54d51df

11 files changed

+1575
-1029
lines changed

doctests/dt_bitmap.py

Lines changed: 117 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@
66
"""
77
import redis
88

9-
r = redis.Redis(decode_responses=True)
9+
# Connect without the usual `decode_responses=True` to
10+
# see the binary values in the responses more easily.
11+
r = redis.Redis()
1012
# HIDE_END
1113

1214
# REMOVE_START
13-
r.delete("pings:2024-01-01-00:00")
15+
r.delete("pings:2024-01-01-00:00", "A", "B", "C", "R")
1416
# REMOVE_END
1517

1618
# STEP_START ping
@@ -38,3 +40,116 @@
3840
# REMOVE_START
3941
assert res4 == 1
4042
# REMOVE_END
43+
44+
# STEP_START bitop_setup
45+
r.setbit("A", 0, 1)
46+
r.setbit("A", 1, 1)
47+
r.setbit("A", 3, 1)
48+
r.setbit("A", 4, 1)
49+
50+
res5 = r.get("A")
51+
print("{:08b}".format(int.from_bytes(res5, "big")))
52+
# >>> 11011000
53+
54+
r.setbit("B", 3, 1)
55+
r.setbit("B", 4, 1)
56+
r.setbit("B", 7, 1)
57+
58+
res6 = r.get("B")
59+
print("{:08b}".format(int.from_bytes(res6, "big")))
60+
# >>> 00011001
61+
62+
r.setbit("C", 1, 1)
63+
r.setbit("C", 2, 1)
64+
r.setbit("C", 4, 1)
65+
r.setbit("C", 5, 1)
66+
67+
res7 = r.get("C")
68+
print("{:08b}".format(int.from_bytes(res7, "big")))
69+
# >>> 01101100
70+
# STEP_END
71+
# REMOVE_START
72+
assert int.from_bytes(res5, "big") == 0b11011000
73+
assert int.from_bytes(res6, "big") == 0b00011001
74+
assert int.from_bytes(res7, "big") == 0b01101100
75+
# REMOVE_END
76+
77+
# STEP_START bitop_and
78+
r.bitop("AND", "R", "A", "B", "C")
79+
res8 = r.get("R")
80+
print("{:08b}".format(int.from_bytes(res8, "big")))
81+
# >>> 00001000
82+
# STEP_END
83+
# REMOVE_START
84+
assert int.from_bytes(res8, "big") == 0b00001000
85+
# REMOVE_END
86+
87+
# STEP_START bitop_or
88+
r.bitop("OR", "R", "A", "B", "C")
89+
res9 = r.get("R")
90+
print("{:08b}".format(int.from_bytes(res9, "big")))
91+
# >>> 11111101
92+
# STEP_END
93+
# REMOVE_START
94+
assert int.from_bytes(res9, "big") == 0b11111101
95+
# REMOVE_END
96+
97+
# STEP_START bitop_xor
98+
r.bitop("XOR", "R", "A", "B")
99+
res10 = r.get("R")
100+
print("{:08b}".format(int.from_bytes(res10, "big")))
101+
# >>> 11000001
102+
# STEP_END
103+
# REMOVE_START
104+
assert int.from_bytes(res10, "big") == 0b11000001
105+
# REMOVE_END
106+
107+
# STEP_START bitop_not
108+
r.bitop("NOT", "R", "A")
109+
res11 = r.get("R")
110+
print("{:08b}".format(int.from_bytes(res11, "big")))
111+
# >>> 00100111
112+
# STEP_END
113+
# REMOVE_START
114+
assert int.from_bytes(res11, "big") == 0b00100111
115+
# REMOVE_END
116+
117+
# STEP_START bitop_diff
118+
r.bitop("DIFF", "R", "A", "B", "C")
119+
res12 = r.get("R")
120+
print("{:08b}".format(int.from_bytes(res12, "big")))
121+
# >>> 10000000
122+
# STEP_END
123+
# REMOVE_START
124+
assert int.from_bytes(res12, "big") == 0b10000000
125+
# REMOVE_END
126+
127+
# STEP_START bitop_diff1
128+
r.bitop("DIFF1", "R", "A", "B", "C")
129+
res13 = r.get("R")
130+
print("{:08b}".format(int.from_bytes(res13, "big")))
131+
# >>> 00100101
132+
# STEP_END
133+
# REMOVE_START
134+
assert int.from_bytes(res13, "big") == 0b00100101
135+
# REMOVE_END
136+
137+
# STEP_START bitop_andor
138+
r.bitop("ANDOR", "R", "A", "B", "C")
139+
res14 = r.get("R")
140+
print("{:08b}".format(int.from_bytes(res14, "big")))
141+
# >>> 01011000
142+
# STEP_END
143+
# REMOVE_START
144+
assert int.from_bytes(res14, "big") == 0b01011000
145+
# REMOVE_END
146+
147+
# STEP_START bitop_one
148+
r.bitop("ONE", "R", "A", "B", "C")
149+
res15 = r.get("R")
150+
print("{:08b}".format(int.from_bytes(res15, "big")))
151+
# >>> 10100101
152+
# STEP_END
153+
# REMOVE_START
154+
assert int.from_bytes(res15, "big") == 0b10100101
155+
# REMOVE_END

redis/_parsers/base.py

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
from typing import Awaitable, Callable, List, Optional, Protocol, Union
66

77
from redis.maintenance_events import (
8-
MaintenanceEvent,
9-
NodeFailedOverEvent,
10-
NodeFailingOverEvent,
11-
NodeMigratedEvent,
12-
NodeMigratingEvent,
13-
NodeMovingEvent,
8+
MaintenanceNotification,
9+
NodeFailedOverNotification,
10+
NodeFailingOverNotification,
11+
NodeMigratedNotification,
12+
NodeMigratingNotification,
13+
NodeMovingNotification,
1414
)
1515

1616
if sys.version_info.major >= 3 and sys.version_info.minor >= 11:
@@ -175,14 +175,14 @@ class MaintenanceNotificationsParser:
175175

176176
@staticmethod
177177
def parse_maintenance_start_msg(response, notification_type):
178-
# Expected message format is: <event_type> <seq_number> <time>
178+
# Expected message format is: <notification_type> <seq_number> <time>
179179
id = response[1]
180180
ttl = response[2]
181181
return notification_type(id, ttl)
182182

183183
@staticmethod
184184
def parse_maintenance_completed_msg(response, notification_type):
185-
# Expected message format is: <event_type> <seq_number>
185+
# Expected message format is: <notification_type> <seq_number>
186186
id = response[1]
187187
return notification_type(id)
188188

@@ -200,7 +200,7 @@ def parse_moving_msg(response):
200200
host, port = value.split(":")
201201
port = int(port) if port is not None else None
202202

203-
return NodeMovingEvent(id, host, port, ttl)
203+
return NodeMovingNotification(id, host, port, ttl)
204204

205205

206206
_INVALIDATION_MESSAGE = "invalidate"
@@ -217,25 +217,27 @@ def parse_moving_msg(response):
217217
_FAILED_OVER_MESSAGE,
218218
)
219219

220-
MSG_TYPE_TO_EVENT_PARSER_MAPPING: dict[str, tuple[type[MaintenanceEvent], Callable]] = {
220+
MSG_TYPE_TO_MAINT_NOTIFICATION_PARSER_MAPPING: dict[
221+
str, tuple[type[MaintenanceNotification], Callable]
222+
] = {
221223
_MIGRATING_MESSAGE: (
222-
NodeMigratingEvent,
224+
NodeMigratingNotification,
223225
MaintenanceNotificationsParser.parse_maintenance_start_msg,
224226
),
225227
_MIGRATED_MESSAGE: (
226-
NodeMigratedEvent,
228+
NodeMigratedNotification,
227229
MaintenanceNotificationsParser.parse_maintenance_completed_msg,
228230
),
229231
_FAILING_OVER_MESSAGE: (
230-
NodeFailingOverEvent,
232+
NodeFailingOverNotification,
231233
MaintenanceNotificationsParser.parse_maintenance_start_msg,
232234
),
233235
_FAILED_OVER_MESSAGE: (
234-
NodeFailedOverEvent,
236+
NodeFailedOverNotification,
235237
MaintenanceNotificationsParser.parse_maintenance_completed_msg,
236238
),
237239
_MOVING_MESSAGE: (
238-
NodeMovingEvent,
240+
NodeMovingNotification,
239241
MaintenanceNotificationsParser.parse_moving_msg,
240242
),
241243
}
@@ -273,14 +275,20 @@ def handle_push_response(self, response, **kwargs):
273275
return self.invalidation_push_handler_func(response)
274276

275277
if msg_type == _MOVING_MESSAGE and self.node_moving_push_handler_func:
276-
parser_function = MSG_TYPE_TO_EVENT_PARSER_MAPPING[msg_type][1]
278+
parser_function = MSG_TYPE_TO_MAINT_NOTIFICATION_PARSER_MAPPING[
279+
msg_type
280+
][1]
277281

278282
notification = parser_function(response)
279283
return self.node_moving_push_handler_func(notification)
280284

281285
if msg_type in _MAINTENANCE_MESSAGES and self.maintenance_push_handler_func:
282-
parser_function = MSG_TYPE_TO_EVENT_PARSER_MAPPING[msg_type][1]
283-
notification_type = MSG_TYPE_TO_EVENT_PARSER_MAPPING[msg_type][0]
286+
parser_function = MSG_TYPE_TO_MAINT_NOTIFICATION_PARSER_MAPPING[
287+
msg_type
288+
][1]
289+
notification_type = MSG_TYPE_TO_MAINT_NOTIFICATION_PARSER_MAPPING[
290+
msg_type
291+
][0]
284292
notification = parser_function(response, notification_type)
285293

286294
if notification is not None:
@@ -342,13 +350,19 @@ async def handle_push_response(self, response, **kwargs):
342350
msg_type = msg_type.decode()
343351

344352
if msg_type == _MOVING_MESSAGE and self.node_moving_push_handler_func:
345-
parser_function = MSG_TYPE_TO_EVENT_PARSER_MAPPING[msg_type][1]
353+
parser_function = MSG_TYPE_TO_MAINT_NOTIFICATION_PARSER_MAPPING[
354+
msg_type
355+
][1]
346356
notification = parser_function(response)
347357
return await self.node_moving_push_handler_func(notification)
348358

349359
if msg_type in _MAINTENANCE_MESSAGES and self.maintenance_push_handler_func:
350-
parser_function = MSG_TYPE_TO_EVENT_PARSER_MAPPING[msg_type][1]
351-
notification_type = MSG_TYPE_TO_EVENT_PARSER_MAPPING[msg_type][0]
360+
parser_function = MSG_TYPE_TO_MAINT_NOTIFICATION_PARSER_MAPPING[
361+
msg_type
362+
][1]
363+
notification_type = MSG_TYPE_TO_MAINT_NOTIFICATION_PARSER_MAPPING[
364+
msg_type
365+
][0]
352366
notification = parser_function(response, notification_type)
353367

354368
if notification is not None:

redis/client.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@
5757
)
5858
from redis.lock import Lock
5959
from redis.maintenance_events import (
60-
MaintenanceEventPoolHandler,
61-
MaintenanceEventsConfig,
60+
MaintNotificationsConfig,
61+
MaintNotificationsPoolHandler,
6262
)
6363
from redis.retry import Retry
6464
from redis.utils import (
@@ -248,7 +248,7 @@ def __init__(
248248
cache: Optional[CacheInterface] = None,
249249
cache_config: Optional[CacheConfig] = None,
250250
event_dispatcher: Optional[EventDispatcher] = None,
251-
maintenance_events_config: Optional[MaintenanceEventsConfig] = None,
251+
maint_notifications_config: Optional[MaintNotificationsConfig] = None,
252252
) -> None:
253253
"""
254254
Initialize a new Redis client.
@@ -373,22 +373,22 @@ def __init__(
373373
]:
374374
raise RedisError("Client caching is only supported with RESP version 3")
375375

376-
if maintenance_events_config and self.connection_pool.get_protocol() not in [
376+
if maint_notifications_config and self.connection_pool.get_protocol() not in [
377377
3,
378378
"3",
379379
]:
380380
raise RedisError(
381381
"Push handlers on connection are only supported with RESP version 3"
382382
)
383-
if maintenance_events_config and maintenance_events_config.enabled:
384-
self.maintenance_events_pool_handler = MaintenanceEventPoolHandler(
385-
self.connection_pool, maintenance_events_config
383+
if maint_notifications_config and maint_notifications_config.enabled:
384+
self.maint_notifications_pool_handler = MaintNotificationsPoolHandler(
385+
self.connection_pool, maint_notifications_config
386386
)
387-
self.connection_pool.set_maintenance_events_pool_handler(
388-
self.maintenance_events_pool_handler
387+
self.connection_pool.set_maint_notifications_pool_handler(
388+
self.maint_notifications_pool_handler
389389
)
390390
else:
391-
self.maintenance_events_pool_handler = None
391+
self.maint_notifications_pool_handler = None
392392

393393
self.single_connection_lock = threading.RLock()
394394
self.connection = None
@@ -587,15 +587,15 @@ def monitor(self):
587587
return Monitor(self.connection_pool)
588588

589589
def client(self):
590-
maintenance_events_config = (
590+
maint_notifications_config = (
591591
None
592-
if self.maintenance_events_pool_handler is None
593-
else self.maintenance_events_pool_handler.config
592+
if self.maint_notifications_pool_handler is None
593+
else self.maint_notifications_pool_handler.config
594594
)
595595
return self.__class__(
596596
connection_pool=self.connection_pool,
597597
single_connection_client=True,
598-
maintenance_events_config=maintenance_events_config,
598+
maint_notifications_config=maint_notifications_config,
599599
)
600600

601601
def __enter__(self):

0 commit comments

Comments
 (0)