Tracking: BCAST: parsing of the options + skeleton.

This commit is contained in:
antirez
2020-02-10 17:18:11 +01:00
parent f53cc00c09
commit dfe126f3e9
4 changed files with 73 additions and 19 deletions

View File

@ -154,6 +154,7 @@ client *createClient(connection *conn) {
c->peerid = NULL;
c->client_list_node = NULL;
c->client_tracking_redirection = 0;
c->client_tracking_prefix_nodes = NULL;
c->auth_callback = NULL;
c->auth_callback_privdata = NULL;
c->auth_module = NULL;
@ -2219,38 +2220,72 @@ NULL
UNIT_MILLISECONDS) != C_OK) return;
pauseClients(duration);
addReply(c,shared.ok);
} else if (!strcasecmp(c->argv[1]->ptr,"tracking") &&
(c->argc == 3 || c->argc == 5))
{
/* CLIENT TRACKING (on|off) [REDIRECT <id>] */
} else if (!strcasecmp(c->argv[1]->ptr,"tracking") && c->argc >= 3) {
/* CLIENT TRACKING (on|off) [REDIRECT <id>] [BCAST] [PREFIX first]
* [PREFIX second] ... */
long long redir = 0;
int bcast = 0;
robj **prefix;
size_t numprefix = 0;
/* Parse the redirection option: we'll require the client with
* the specified ID to exist right now, even if it is possible
* it will get disconnected later. */
if (c->argc == 5) {
if (strcasecmp(c->argv[3]->ptr,"redirect") != 0) {
addReply(c,shared.syntaxerr);
return;
} else {
if (getLongLongFromObjectOrReply(c,c->argv[4],&redir,NULL) !=
/* Parse the options. */
if (for int j = 3; j < argc; j++) {
int moreargs = (c->argc-1) - j;
if (!strcasecmp(c->argv[j]->ptr,"redirect") && moreargs) {
j++;
if (getLongLongFromObjectOrReply(c,c->argv[j],&redir,NULL) !=
C_OK) return;
/* We will require the client with the specified ID to exist
* right now, even if it is possible that it gets disconnected
* later. Still a valid sanity check. */
if (lookupClientByID(redir) == NULL) {
addReplyError(c,"The client ID you want redirect to "
"does not exist");
return;
}
} else if (!strcasecmp(c->argv[j]->ptr,"bcast")) {
bcast++;
} else if (!strcasecmp(c->argv[j]->ptr,"prefix") && morearg) {
j++;
prefix = zrealloc(sizeof(robj*)*(numprefix+1));
prefix[numprefix++] = argv[j];
} else {
addReply(c,shared.syntaxerr);
return;
}
}
/* Make sure options are compatible among each other and with the
* current state of the client. */
if (!bcast && numprefix) {
addReplyError("PREFIX option requires BCAST mode to be enabled");
zfree(prefix);
return;
}
if (client->flags & CLIENT_TRACKING) {
int oldbcast = !!client->flags & CLIENT_TRACKING_BCAST;
if (oldbcast != bcast) {
}
addReplyError(
"You can't switch BCAST mode on/off before disabling "
"tracking for this client, and then re-enabling it with "
"a different mode.");
zfree(prefix);
return;
}
/* Options are ok: enable or disable the tracking for this client. */
if (!strcasecmp(c->argv[2]->ptr,"on")) {
enableTracking(c,redir);
enableTracking(c,redir,bcast,prefix,numprefix);
} else if (!strcasecmp(c->argv[2]->ptr,"off")) {
disableTracking(c);
} else {
addReply(c,shared.syntaxerr);
return;
}
zfree(prefix);
addReply(c,shared.ok);
} else if (!strcasecmp(c->argv[1]->ptr,"getredir") && c->argc == 2) {
/* CLIENT GETREDIR */