Skip to content

Commit 139bcbb

Browse files
Support CLIENT TRACKING (#1612)
Co-authored-by: Chayim I. Kirshen <[email protected]>
1 parent 1bcdf2d commit 139bcbb

File tree

2 files changed

+120
-0
lines changed

2 files changed

+120
-0
lines changed

redis/commands/core.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,104 @@ def client_id(self, **kwargs):
479479
"""
480480
return self.execute_command("CLIENT ID", **kwargs)
481481

482+
def client_tracking_on(
483+
self,
484+
clientid=None,
485+
prefix=[],
486+
bcast=False,
487+
optin=False,
488+
optout=False,
489+
noloop=False,
490+
):
491+
"""
492+
Turn on the tracking mode.
493+
For more information about the options look at client_tracking func.
494+
495+
See https://redis.io/commands/client-tracking
496+
"""
497+
return self.client_tracking(
498+
True, clientid, prefix, bcast, optin, optout, noloop
499+
)
500+
501+
def client_tracking_off(
502+
self,
503+
clientid=None,
504+
prefix=[],
505+
bcast=False,
506+
optin=False,
507+
optout=False,
508+
noloop=False,
509+
):
510+
"""
511+
Turn off the tracking mode.
512+
For more information about the options look at client_tracking func.
513+
514+
See https://redis.io/commands/client-tracking
515+
"""
516+
return self.client_tracking(
517+
False, clientid, prefix, bcast, optin, optout, noloop
518+
)
519+
520+
def client_tracking(
521+
self,
522+
on=True,
523+
clientid=None,
524+
prefix=[],
525+
bcast=False,
526+
optin=False,
527+
optout=False,
528+
noloop=False,
529+
**kwargs,
530+
):
531+
"""
532+
Enables the tracking feature of the Redis server, that is used
533+
for server assisted client side caching.
534+
535+
``on`` indicate for tracking on or tracking off. The dafualt is on.
536+
537+
``clientid`` send invalidation messages to the connection with
538+
the specified ID.
539+
540+
``bcast`` enable tracking in broadcasting mode. In this mode
541+
invalidation messages are reported for all the prefixes
542+
specified, regardless of the keys requested by the connection.
543+
544+
``optin`` when broadcasting is NOT active, normally don't track
545+
keys in read only commands, unless they are called immediately
546+
after a CLIENT CACHING yes command.
547+
548+
``optout`` when broadcasting is NOT active, normally track keys in
549+
read only commands, unless they are called immediately after a
550+
CLIENT CACHING no command.
551+
552+
``noloop`` don't send notifications about keys modified by this
553+
connection itself.
554+
555+
``prefix`` for broadcasting, register a given key prefix, so that
556+
notifications will be provided only for keys starting with this string.
557+
558+
See https://redis.io/commands/client-tracking
559+
"""
560+
561+
if len(prefix) != 0 and bcast is False:
562+
raise DataError("Prefix can only be used with bcast")
563+
564+
pieces = ["ON"] if on else ["OFF"]
565+
if clientid is not None:
566+
pieces.extend(["REDIRECT", clientid])
567+
for p in prefix:
568+
pieces.extend(["PREFIX", p])
569+
if bcast:
570+
pieces.append("BCAST")
571+
if optin:
572+
pieces.append("OPTIN")
573+
if optout:
574+
pieces.append("OPTOUT")
575+
if noloop:
576+
pieces.append("NOLOOP")
577+
578+
return self.execute_command("CLIENT TRACKING", *pieces)
579+
482580
def client_trackinginfo(self, **kwargs):
483581
"""
484582
Returns the information about the current client connection's

tests/test_commands.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,28 @@ def test_client_trackinginfo(self, r):
396396
assert len(res) > 2
397397
assert "prefixes" in res
398398

399+
@pytest.mark.onlynoncluster
400+
@skip_if_server_version_lt("6.0.0")
401+
def test_client_tracking(self, r, r2):
402+
403+
# simple case
404+
assert r.client_tracking_on()
405+
assert r.client_tracking_off()
406+
407+
# id based
408+
client_id = r.client_id()
409+
assert r.client_tracking_on(client_id)
410+
assert r.client_tracking_off(client_id)
411+
412+
# id exists
413+
client_id = r2.client_id()
414+
assert r.client_tracking_on(client_id)
415+
assert r2.client_tracking_off(client_id)
416+
417+
# now with some prefixes
418+
with pytest.raises(exceptions.DataError):
419+
assert r.client_tracking_on(prefix=["foo", "bar", "blee"])
420+
399421
@pytest.mark.onlynoncluster
400422
@skip_if_server_version_lt("5.0.0")
401423
def test_client_unblock(self, r):

0 commit comments

Comments
 (0)