mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-23 00:28:26 -05:00
Propagate GETSET and SET-GET as SET (#7957)
- Generates a more backwards compatible command stream - Slightly more efficient execution in replica/AOF - Add a test for coverage
This commit is contained in:
parent
1a91a2700b
commit
9122379abc
@ -90,7 +90,7 @@ void setGenericCommand(client *c, int flags, robj *key, robj *val, robj *expire,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (flags & OBJ_SET_GET) {
|
if (flags & OBJ_SET_GET) {
|
||||||
getGenericCommand(c);
|
getGenericCommand(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
genericSetKey(c,c->db,key,val,flags & OBJ_SET_KEEPTTL,1);
|
genericSetKey(c,c->db,key,val,flags & OBJ_SET_KEEPTTL,1);
|
||||||
@ -160,6 +160,24 @@ void setCommand(client *c) {
|
|||||||
|
|
||||||
c->argv[2] = tryObjectEncoding(c->argv[2]);
|
c->argv[2] = tryObjectEncoding(c->argv[2]);
|
||||||
setGenericCommand(c,flags,c->argv[1],c->argv[2],expire,unit,NULL,NULL);
|
setGenericCommand(c,flags,c->argv[1],c->argv[2],expire,unit,NULL,NULL);
|
||||||
|
|
||||||
|
/* Propagate without the GET argument */
|
||||||
|
if (flags & OBJ_SET_GET) {
|
||||||
|
int argc = 0;
|
||||||
|
robj **argv = zmalloc((c->argc-1)*sizeof(robj*));
|
||||||
|
for (j=0; j < c->argc; j++) {
|
||||||
|
char *a = c->argv[j]->ptr;
|
||||||
|
/* Skip GET which may be repeated multiple times. */
|
||||||
|
if (j >= 3 &&
|
||||||
|
(a[0] == 'g' || a[0] == 'G') &&
|
||||||
|
(a[1] == 'e' || a[1] == 'E') &&
|
||||||
|
(a[2] == 't' || a[2] == 'T') && a[3] == '\0')
|
||||||
|
continue;
|
||||||
|
argv[argc++] = c->argv[j];
|
||||||
|
incrRefCount(c->argv[j]);
|
||||||
|
}
|
||||||
|
replaceClientCommandVector(c, argc, argv);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setnxCommand(client *c) {
|
void setnxCommand(client *c) {
|
||||||
@ -201,6 +219,11 @@ void getsetCommand(client *c) {
|
|||||||
setKey(c,c->db,c->argv[1],c->argv[2]);
|
setKey(c,c->db,c->argv[1],c->argv[2]);
|
||||||
notifyKeyspaceEvent(NOTIFY_STRING,"set",c->argv[1],c->db->id);
|
notifyKeyspaceEvent(NOTIFY_STRING,"set",c->argv[1],c->db->id);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
|
|
||||||
|
/* Propagate as SET command */
|
||||||
|
robj *setcmd = createStringObject("SET",3);
|
||||||
|
rewriteClientCommandArgument(c,0,setcmd);
|
||||||
|
decrRefCount(setcmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setrangeCommand(client *c) {
|
void setrangeCommand(client *c) {
|
||||||
|
@ -77,6 +77,27 @@ start_server {tags {"repl"}} {
|
|||||||
assert_equal [$A debug digest] [$B debug digest]
|
assert_equal [$A debug digest] [$B debug digest]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test {GETSET replication} {
|
||||||
|
$A config resetstat
|
||||||
|
$A config set loglevel debug
|
||||||
|
$B config set loglevel debug
|
||||||
|
r set test foo
|
||||||
|
assert_equal [r getset test bar] foo
|
||||||
|
wait_for_condition 500 10 {
|
||||||
|
[$A get test] eq "bar"
|
||||||
|
} else {
|
||||||
|
fail "getset wasn't propagated"
|
||||||
|
}
|
||||||
|
assert_equal [r set test vaz get] bar
|
||||||
|
wait_for_condition 500 10 {
|
||||||
|
[$A get test] eq "vaz"
|
||||||
|
} else {
|
||||||
|
fail "set get wasn't propagated"
|
||||||
|
}
|
||||||
|
assert_match {*calls=3,*} [cmdrstat set $A]
|
||||||
|
assert_match {} [cmdrstat getset $A]
|
||||||
|
}
|
||||||
|
|
||||||
test {BRPOPLPUSH replication, when blocking against empty list} {
|
test {BRPOPLPUSH replication, when blocking against empty list} {
|
||||||
$A config resetstat
|
$A config resetstat
|
||||||
set rd [redis_deferring_client]
|
set rd [redis_deferring_client]
|
||||||
|
Loading…
Reference in New Issue
Block a user