summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/t_string.c25
-rw-r--r--tests/integration/replication.tcl21
2 files changed, 45 insertions, 1 deletions
diff --git a/src/t_string.c b/src/t_string.c
index 188f27dc0..e8b37663d 100644
--- a/src/t_string.c
+++ b/src/t_string.c
@@ -90,7 +90,7 @@ void setGenericCommand(client *c, int flags, robj *key, robj *val, robj *expire,
}
if (flags & OBJ_SET_GET) {
- getGenericCommand(c);
+ getGenericCommand(c);
}
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]);
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) {
@@ -201,6 +219,11 @@ void getsetCommand(client *c) {
setKey(c,c->db,c->argv[1],c->argv[2]);
notifyKeyspaceEvent(NOTIFY_STRING,"set",c->argv[1],c->db->id);
server.dirty++;
+
+ /* Propagate as SET command */
+ robj *setcmd = createStringObject("SET",3);
+ rewriteClientCommandArgument(c,0,setcmd);
+ decrRefCount(setcmd);
}
void setrangeCommand(client *c) {
diff --git a/tests/integration/replication.tcl b/tests/integration/replication.tcl
index fb0b9b965..6c437ba71 100644
--- a/tests/integration/replication.tcl
+++ b/tests/integration/replication.tcl
@@ -77,6 +77,27 @@ start_server {tags {"repl"}} {
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} {
$A config resetstat
set rd [redis_deferring_client]