Tracking: add CLIENT TRACKINGINFO subcommand (#7309)

Add CLIENT TRACKINGINFO subcommand

Co-authored-by: Oran Agra <oran@redislabs.com>
This commit is contained in:
zhaozhao.zz 2020-12-27 19:14:39 +08:00 committed by GitHub
parent f44186e575
commit 299f9ebffa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 142 additions and 1 deletions

View File

@ -2384,9 +2384,10 @@ void clientCommand(client *c) {
"REPLY (on|off|skip) -- Control the replies sent to the current connection.",
"SETNAME <name> -- Assign the name <name> to the current connection.",
"UNBLOCK <clientid> [TIMEOUT|ERROR] -- Unblock the specified blocked client.",
"TRACKING (on|off) [REDIRECT <id>] [BCAST] [PREFIX first] [PREFIX second] [OPTIN] [OPTOUT]... -- Enable client keys tracking for client side caching.",
"TRACKING (on|off) [REDIRECT <id>] [BCAST] [PREFIX first] [PREFIX second] [OPTIN] [OPTOUT] [NOLOOP]... -- Enable client keys tracking for client side caching.",
"CACHING (yes|no) -- Enable/Disable tracking of the keys for next command in OPTIN/OPTOUT mode.",
"GETREDIR -- Return the client ID we are redirecting to when tracking is enabled.",
"TRACKINGINFO -- Return information about current client's tracking status.",
NULL
};
addReplyHelp(c, help);
@ -2753,6 +2754,67 @@ NULL
} else {
addReplyLongLong(c,-1);
}
} else if (!strcasecmp(c->argv[1]->ptr,"trackinginfo") && c->argc == 2) {
addReplyMapLen(c,3);
/* Flags */
addReplyBulkCString(c,"flags");
void *arraylen_ptr = addReplyDeferredLen(c);
int numflags = 0;
addReplyBulkCString(c,c->flags & CLIENT_TRACKING ? "on" : "off");
numflags++;
if (c->flags & CLIENT_TRACKING_BCAST) {
addReplyBulkCString(c,"bcast");
numflags++;
}
if (c->flags & CLIENT_TRACKING_OPTIN) {
addReplyBulkCString(c,"optin");
numflags++;
if (c->flags & CLIENT_TRACKING_CACHING) {
addReplyBulkCString(c,"caching-yes");
numflags++;
}
}
if (c->flags & CLIENT_TRACKING_OPTOUT) {
addReplyBulkCString(c,"optout");
numflags++;
if (c->flags & CLIENT_TRACKING_CACHING) {
addReplyBulkCString(c,"caching-no");
numflags++;
}
}
if (c->flags & CLIENT_TRACKING_NOLOOP) {
addReplyBulkCString(c,"noloop");
numflags++;
}
if (c->flags & CLIENT_TRACKING_BROKEN_REDIR) {
addReplyBulkCString(c,"broken_redirect");
numflags++;
}
setDeferredSetLen(c,arraylen_ptr,numflags);
/* Redirect */
addReplyBulkCString(c,"redirect");
if (c->flags & CLIENT_TRACKING) {
addReplyLongLong(c,c->client_tracking_redirection);
} else {
addReplyLongLong(c,-1);
}
/* Prefixes */
addReplyBulkCString(c,"prefixes");
if (c->client_tracking_prefixes) {
addReplyArrayLen(c,raxSize(c->client_tracking_prefixes));
raxIterator ri;
raxStart(&ri,c->client_tracking_prefixes);
raxSeek(&ri,"^",NULL,0);
while(raxNext(&ri)) {
addReplyBulkCBuffer(c,ri.key,ri.key_len);
}
raxStop(&ri);
} else {
addReplyArrayLen(c,0);
}
} else {
addReplyErrorFormat(c, "Unknown subcommand or wrong number of arguments for '%s'. Try CLIENT HELP", (char*)c->argv[1]->ptr);
}

View File

@ -398,6 +398,85 @@ start_server {tags {"tracking"}} {
assert {$total_prefixes == 1}
}
test {CLIENT TRACKINGINFO provides reasonable results when tracking off} {
r CLIENT TRACKING off
set res [r client trackinginfo]
set flags [dict get $res flags]
assert_equal {off} $flags
set redirect [dict get $res redirect]
assert_equal {-1} $redirect
set prefixes [dict get $res prefixes]
assert_equal {} $prefixes
}
test {CLIENT TRACKINGINFO provides reasonable results when tracking on} {
r CLIENT TRACKING on
set res [r client trackinginfo]
set flags [dict get $res flags]
assert_equal {on} $flags
set redirect [dict get $res redirect]
assert_equal {0} $redirect
set prefixes [dict get $res prefixes]
assert_equal {} $prefixes
}
test {CLIENT TRACKINGINFO provides reasonable results when tracking on with options} {
r CLIENT TRACKING on REDIRECT $redir_id noloop
set res [r client trackinginfo]
set flags [dict get $res flags]
assert_equal {on noloop} $flags
set redirect [dict get $res redirect]
assert_equal $redir_id $redirect
set prefixes [dict get $res prefixes]
assert_equal {} $prefixes
}
test {CLIENT TRACKINGINFO provides reasonable results when tracking optin} {
r CLIENT TRACKING off
r CLIENT TRACKING on optin
set res [r client trackinginfo]
set flags [dict get $res flags]
assert_equal {on optin} $flags
set redirect [dict get $res redirect]
assert_equal {0} $redirect
set prefixes [dict get $res prefixes]
assert_equal {} $prefixes
r CLIENT CACHING yes
set res [r client trackinginfo]
set flags [dict get $res flags]
assert_equal {on optin caching-yes} $flags
}
test {CLIENT TRACKINGINFO provides reasonable results when tracking optout} {
r CLIENT TRACKING off
r CLIENT TRACKING on optout
set res [r client trackinginfo]
set flags [dict get $res flags]
assert_equal {on optout} $flags
set redirect [dict get $res redirect]
assert_equal {0} $redirect
set prefixes [dict get $res prefixes]
assert_equal {} $prefixes
r CLIENT CACHING no
set res [r client trackinginfo]
set flags [dict get $res flags]
assert_equal {on optout caching-no} $flags
}
test {CLIENT TRACKINGINFO provides reasonable results when tracking bcast mode} {
r CLIENT TRACKING off
r CLIENT TRACKING on BCAST PREFIX foo PREFIX bar
set res [r client trackinginfo]
set flags [dict get $res flags]
assert_equal {on bcast} $flags
set redirect [dict get $res redirect]
assert_equal {0} $redirect
set prefixes [lsort [dict get $res prefixes]]
assert_equal {bar foo} $prefixes
}
$rd_redirection close
$rd close
}