Skip to content

Commit 8a5740d

Browse files
gniadecksazzad16
andauthored
Add support for WAITAOF command (#3393)
* #3344 Add support for new redis command WAITAOF * PR Comments (#3344) * Change casted type in builder (#3344) * Fix test (#3344) --------- Co-authored-by: komp15 <[email protected]> Co-authored-by: M Sazzadul Hoque <[email protected]>
1 parent a916994 commit 8a5740d

18 files changed

+146
-7
lines changed

src/main/java/redis/clients/jedis/BuilderFactory.java

+10-5
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,12 @@
44
import java.util.*;
55
import java.util.stream.Collectors;
66

7-
import redis.clients.jedis.exceptions.JedisException;
87
import redis.clients.jedis.resps.StreamConsumerFullInfo;
98
import redis.clients.jedis.resps.StreamFullInfo;
109
import redis.clients.jedis.resps.StreamGroupFullInfo;
1110
import redis.clients.jedis.resps.LCSMatchResult.MatchedPosition;
1211
import redis.clients.jedis.resps.LCSMatchResult.Position;
1312
import redis.clients.jedis.resps.*;
14-
import redis.clients.jedis.search.aggr.AggregationResult;
15-
import redis.clients.jedis.timeseries.TSKeyedElements;
16-
import redis.clients.jedis.timeseries.TSElement;
17-
import redis.clients.jedis.timeseries.TSKeyValue;
1813
import redis.clients.jedis.util.DoublePrecision;
1914
import redis.clients.jedis.util.JedisByteHashMap;
2015
import redis.clients.jedis.util.KeyValue;
@@ -421,6 +416,16 @@ public String toString() {
421416
}
422417
};
423418

419+
public static final Builder<KeyValue<Long, Long>> LONG_LONG_PAIR = new Builder<KeyValue<Long, Long>>() {
420+
@Override
421+
@SuppressWarnings("unchecked")
422+
public KeyValue<Long, Long> build(Object data) {
423+
if (data == null) return null;
424+
List<Object> dataList = (List<Object>) data;
425+
return new KeyValue<>(LONG.build(dataList.get(0)), LONG.build(dataList.get(1)));
426+
}
427+
};
428+
424429
public static final Builder<List<KeyValue<String, List<String>>>> KEYED_STRING_LIST_LIST
425430
= new Builder<List<KeyValue<String, List<String>>>>() {
426431
@Override

src/main/java/redis/clients/jedis/ClusterCommandObjects.java

+7
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import redis.clients.jedis.params.ScanParams;
1111
import redis.clients.jedis.resps.ScanResult;
1212
import redis.clients.jedis.util.JedisClusterHashTag;
13+
import redis.clients.jedis.util.KeyValue;
1314

1415
public class ClusterCommandObjects extends CommandObjects {
1516

@@ -97,4 +98,10 @@ public final CommandObject<ScanResult<byte[]>> scan(byte[] cursor, ScanParams pa
9798
public final CommandObject<Long> waitReplicas(int replicas, long timeout) {
9899
throw new UnsupportedOperationException(CLUSTER_UNSUPPORTED_MESSAGE);
99100
}
101+
102+
@Override
103+
public CommandObject<KeyValue<Long, Long>> waitAOF(long numLocal, long numReplicas, long timeout) {
104+
throw new UnsupportedOperationException(CLUSTER_UNSUPPORTED_MESSAGE);
105+
}
106+
100107
}

src/main/java/redis/clients/jedis/CommandObjects.java

+12
Original file line numberDiff line numberDiff line change
@@ -3132,6 +3132,18 @@ public final CommandObject<Long> waitReplicas(byte[] sampleKey, int replicas, lo
31323132
return new CommandObject<>(commandArguments(WAIT).add(replicas).add(timeout).processKey(sampleKey), BuilderFactory.LONG);
31333133
}
31343134

3135+
public CommandObject<KeyValue<Long, Long>> waitAOF(long numLocal, long numReplicas, long timeout) {
3136+
return new CommandObject<>(commandArguments(WAITAOF).add(numLocal).add(numReplicas).add(timeout), BuilderFactory.LONG_LONG_PAIR);
3137+
}
3138+
3139+
public CommandObject<KeyValue<Long, Long>> waitAOF(byte[] sampleKey, long numLocal, long numReplicas, long timeout) {
3140+
return new CommandObject<>(commandArguments(WAITAOF).add(numLocal).add(numReplicas).add(timeout).processKey(sampleKey), BuilderFactory.LONG_LONG_PAIR);
3141+
}
3142+
3143+
public CommandObject<KeyValue<Long, Long>> waitAOF(String sampleKey, long numLocal, long numReplicas, long timeout) {
3144+
return new CommandObject<>(commandArguments(WAITAOF).add(numLocal).add(numReplicas).add(timeout).processKey(sampleKey), BuilderFactory.LONG_LONG_PAIR);
3145+
}
3146+
31353147
public final CommandObject<Long> publish(String channel, String message) {
31363148
return new CommandObject<>(commandArguments(PUBLISH).add(channel).add(message), BuilderFactory.LONG);
31373149
}

src/main/java/redis/clients/jedis/Jedis.java

+7
Original file line numberDiff line numberDiff line change
@@ -4389,6 +4389,13 @@ public long waitReplicas(final int replicas, final long timeout) {
43894389
return connection.getIntegerReply();
43904390
}
43914391

4392+
@Override
4393+
public KeyValue<Long, Long> waitAOF(long numLocal, long numReplicas, long timeout) {
4394+
checkIsInMultiOrPipeline();
4395+
connection.sendCommand(WAITAOF, toByteArray(numLocal), toByteArray(numReplicas), toByteArray(timeout));
4396+
return BuilderFactory.LONG_LONG_PAIR.build(connection.getOne());
4397+
}
4398+
43924399
@Override
43934400
public long pfadd(final byte[] key, final byte[]... elements) {
43944401
checkIsInMultiOrPipeline();

src/main/java/redis/clients/jedis/MultiNodePipelineBase.java

+10
Original file line numberDiff line numberDiff line change
@@ -1688,6 +1688,11 @@ public Response<Long> waitReplicas(String sampleKey, int replicas, long timeout)
16881688
return appendCommand(commandObjects.waitReplicas(sampleKey, replicas, timeout));
16891689
}
16901690

1691+
@Override
1692+
public Response<KeyValue<Long, Long>> waitAOF(String sampleKey, long numLocal, long numReplicas, long timeout) {
1693+
return appendCommand(commandObjects.waitAOF(sampleKey, numLocal, numReplicas, timeout));
1694+
}
1695+
16911696
@Override
16921697
public Response<Object> eval(String script, String sampleKey) {
16931698
return appendCommand(commandObjects.eval(script, sampleKey));
@@ -2509,6 +2514,11 @@ public Response<Long> waitReplicas(byte[] sampleKey, int replicas, long timeout)
25092514
return appendCommand(commandObjects.waitReplicas(sampleKey, replicas, timeout));
25102515
}
25112516

2517+
@Override
2518+
public Response<KeyValue<Long, Long>> waitAOF(byte[] sampleKey, long numLocal, long numReplicas, long timeout) {
2519+
return appendCommand(commandObjects.waitAOF(sampleKey, numLocal, numReplicas, timeout));
2520+
}
2521+
25122522
@Override
25132523
public Response<Object> eval(byte[] script, byte[] sampleKey) {
25142524
return appendCommand(commandObjects.eval(script, sampleKey));

src/main/java/redis/clients/jedis/Pipeline.java

+14
Original file line numberDiff line numberDiff line change
@@ -1639,6 +1639,11 @@ public Response<Long> waitReplicas(String sampleKey, int replicas, long timeout)
16391639
return appendCommand(commandObjects.waitReplicas(sampleKey, replicas, timeout));
16401640
}
16411641

1642+
@Override
1643+
public Response<KeyValue<Long, Long>> waitAOF(String sampleKey, long numLocal, long numReplicas, long timeout) {
1644+
return appendCommand(commandObjects.waitAOF(sampleKey, numLocal, numReplicas, timeout));
1645+
}
1646+
16421647
@Override
16431648
public Response<Object> eval(String script, String sampleKey) {
16441649
return appendCommand(commandObjects.eval(script, sampleKey));
@@ -2460,6 +2465,11 @@ public Response<Long> waitReplicas(byte[] sampleKey, int replicas, long timeout)
24602465
return appendCommand(commandObjects.waitReplicas(sampleKey, replicas, timeout));
24612466
}
24622467

2468+
@Override
2469+
public Response<KeyValue<Long, Long>> waitAOF(byte[] sampleKey, long numLocal, long numReplicas, long timeout) {
2470+
return appendCommand(commandObjects.waitAOF(sampleKey, numLocal, numReplicas, timeout));
2471+
}
2472+
24632473
@Override
24642474
public Response<Object> eval(byte[] script, byte[] sampleKey) {
24652475
return appendCommand(commandObjects.eval(script, sampleKey));
@@ -4312,6 +4322,10 @@ public Response<Long> waitReplicas(int replicas, long timeout) {
43124322
return appendCommand(commandObjects.waitReplicas(replicas, timeout));
43134323
}
43144324

4325+
public Response<KeyValue<Long, Long>> waitAOF(long numLocal, long numReplicas, long timeout) {
4326+
return appendCommand(commandObjects.waitAOF(numLocal, numReplicas, timeout));
4327+
}
4328+
43154329
public Response<List<String>> time() {
43164330
return appendCommand(new CommandObject<>(commandObjects.commandArguments(Protocol.Command.TIME), BuilderFactory.STRING_LIST));
43174331
}

src/main/java/redis/clients/jedis/Protocol.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ public static enum Command implements ProtocolCommand {
237237
XADD, XLEN, XDEL, XTRIM, XRANGE, XREVRANGE, XREAD, XACK, XGROUP, XREADGROUP, XPENDING, XCLAIM,
238238
XAUTOCLAIM, XINFO, BITFIELD_RO, ROLE, FAILOVER, GEOSEARCH, GEOSEARCHSTORE, EVAL_RO, EVALSHA_RO,
239239
LOLWUT, EXPIRETIME, PEXPIRETIME, FUNCTION, FCALL, FCALL_RO, LMPOP, BLMPOP, ZMPOP, BZMPOP,
240-
COMMAND, LATENCY, @Deprecated STRALGO;
240+
COMMAND, LATENCY, WAITAOF, @Deprecated STRALGO;
241241

242242
private final byte[] raw;
243243

src/main/java/redis/clients/jedis/ShardedCommandObjects.java

+6
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import redis.clients.jedis.resps.ScanResult;
1313
import redis.clients.jedis.util.Hashing;
1414
import redis.clients.jedis.util.JedisClusterHashTag;
15+
import redis.clients.jedis.util.KeyValue;
1516

1617
public class ShardedCommandObjects extends CommandObjects {
1718

@@ -109,4 +110,9 @@ public final CommandObject<ScanResult<byte[]>> scan(byte[] cursor, ScanParams pa
109110
public final CommandObject<Long> waitReplicas(int replicas, long timeout) {
110111
throw new UnsupportedOperationException();
111112
}
113+
114+
@Override
115+
public CommandObject<KeyValue<Long, Long>> waitAOF(long numLocal, long numReplicas, long timeout) {
116+
throw new UnsupportedOperationException();
117+
}
112118
}

src/main/java/redis/clients/jedis/TransactionBase.java

+10
Original file line numberDiff line numberDiff line change
@@ -1738,6 +1738,11 @@ public Response<Long> waitReplicas(String sampleKey, int replicas, long timeout)
17381738
return appendCommand(commandObjects.waitReplicas(sampleKey, replicas, timeout));
17391739
}
17401740

1741+
@Override
1742+
public Response<KeyValue<Long, Long>> waitAOF(String sampleKey, long numLocal, long numReplicas, long timeout) {
1743+
return appendCommand(commandObjects.waitAOF(sampleKey, numLocal, numReplicas, timeout));
1744+
}
1745+
17411746
@Override
17421747
public Response<Object> eval(String script, String sampleKey) {
17431748
return appendCommand(commandObjects.eval(script, sampleKey));
@@ -2559,6 +2564,11 @@ public Response<Long> waitReplicas(byte[] sampleKey, int replicas, long timeout)
25592564
return appendCommand(commandObjects.waitReplicas(sampleKey, replicas, timeout));
25602565
}
25612566

2567+
@Override
2568+
public Response<KeyValue<Long, Long>> waitAOF(byte[] sampleKey, long numLocal, long numReplicas, long timeout) {
2569+
return appendCommand(commandObjects.waitAOF(sampleKey, numLocal, numReplicas, timeout));
2570+
}
2571+
25622572
@Override
25632573
public Response<Object> eval(byte[] script, byte[] sampleKey) {
25642574
return appendCommand(commandObjects.eval(script, sampleKey));

src/main/java/redis/clients/jedis/UnifiedJedis.java

+10
Original file line numberDiff line numberDiff line change
@@ -3414,6 +3414,16 @@ public long waitReplicas(byte[] sampleKey, int replicas, long timeout) {
34143414
return executeCommand(commandObjects.waitReplicas(sampleKey, replicas, timeout));
34153415
}
34163416

3417+
@Override
3418+
public KeyValue<Long, Long> waitAOF(String sampleKey, long numLocal, long numReplicas, long timeout) {
3419+
return executeCommand(commandObjects.waitAOF(sampleKey, numLocal, numReplicas, timeout));
3420+
}
3421+
3422+
@Override
3423+
public KeyValue<Long, Long> waitAOF(byte[] sampleKey, long numLocal, long numReplicas, long timeout) {
3424+
return executeCommand(commandObjects.waitAOF(sampleKey, numLocal, numReplicas, timeout));
3425+
}
3426+
34173427
@Override
34183428
public Object eval(String script, String sampleKey) {
34193429
return executeCommand(commandObjects.eval(script, sampleKey));

src/main/java/redis/clients/jedis/commands/SampleBinaryKeyedCommands.java

+3
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@
22

33
import java.util.List;
44
import redis.clients.jedis.args.FlushMode;
5+
import redis.clients.jedis.util.KeyValue;
56

67
public interface SampleBinaryKeyedCommands {
78

89
long waitReplicas(byte[] sampleKey, int replicas, long timeout);
910

11+
KeyValue<Long, Long> waitAOF(byte[] sampleKey, long numLocal, long numReplicas, long timeout);
12+
1013
Object eval(byte[] script, byte[] sampleKey);
1114

1215
Object evalsha(byte[] sha1, byte[] sampleKey);

src/main/java/redis/clients/jedis/commands/SampleBinaryKeyedPipelineCommands.java

+3
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@
33
import java.util.List;
44
import redis.clients.jedis.Response;
55
import redis.clients.jedis.args.FlushMode;
6+
import redis.clients.jedis.util.KeyValue;
67

78
public interface SampleBinaryKeyedPipelineCommands {
89

910
Response<Long> waitReplicas(byte[] sampleKey, int replicas, long timeout);
1011

12+
Response<KeyValue<Long, Long>> waitAOF(byte[] sampleKey, long numLocal, long numReplicas, long timeout);
13+
1114
Response<Object> eval(byte[] script, byte[] sampleKey);
1215

1316
Response<Object> evalsha(byte[] sha1, byte[] sampleKey);

src/main/java/redis/clients/jedis/commands/SampleKeyedCommands.java

+3
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@
22

33
import java.util.List;
44
import redis.clients.jedis.args.FlushMode;
5+
import redis.clients.jedis.util.KeyValue;
56

67
public interface SampleKeyedCommands {
78

89
long waitReplicas(String sampleKey, int replicas, long timeout);
910

11+
KeyValue<Long, Long> waitAOF(String sampleKey, long numLocal, long numReplicas, long timeout);
12+
1013
Object eval(String script, String sampleKey);
1114

1215
Object evalsha(String sha1, String sampleKey);

src/main/java/redis/clients/jedis/commands/SampleKeyedPipelineCommands.java

+3
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@
33
import java.util.List;
44
import redis.clients.jedis.Response;
55
import redis.clients.jedis.args.FlushMode;
6+
import redis.clients.jedis.util.KeyValue;
67

78
public interface SampleKeyedPipelineCommands {
89

910
Response<Long> waitReplicas(String sampleKey, int replicas, long timeout);
1011

12+
Response<KeyValue<Long, Long>> waitAOF(String sampleKey, long numLocal, long numReplicas, long timeout);
13+
1114
Response<Object> eval(String script, String sampleKey);
1215

1316
Response<Object> evalsha(String sha1, String sampleKey);

src/main/java/redis/clients/jedis/commands/ServerCommands.java

+16-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import redis.clients.jedis.exceptions.JedisException;
66
import redis.clients.jedis.params.LolwutParams;
77
import redis.clients.jedis.params.ShutdownParams;
8+
import redis.clients.jedis.util.KeyValue;
89

910
public interface ServerCommands {
1011

@@ -211,7 +212,7 @@ public interface ServerCommands {
211212
String replicaofNoOne();
212213

213214
/**
214-
* Syncrhonous replication of Redis as described here: http://antirez.com/news/66.
215+
* Synchronous replication of Redis as described here: http://antirez.com/news/66.
215216
* <p>
216217
* Blocks until all the previous write commands are successfully transferred and acknowledged by
217218
* at least the specified number of replicas. If the timeout, specified in milliseconds, is
@@ -226,6 +227,20 @@ public interface ServerCommands {
226227
*/
227228
long waitReplicas(int replicas, long timeout);
228229

230+
/**
231+
* Blocks the current client until all the previous write commands are acknowledged as having been
232+
* fsynced to the AOF of the local Redis and/or at least the specified number of replicas.
233+
* <a href="https://redis.io/commands/waitaof/">Redis Documentation</a>
234+
* @param numLocal Number of local instances that are required to acknowledge the sync (0 or 1),
235+
* cannot be non-zero if the local Redis does not have AOF enabled
236+
* @param numReplicas Number of replicas that are required to acknowledge the sync
237+
* @param timeout Timeout in millis of the operation - if 0 timeout is unlimited. If the timeout is reached,
238+
* the command returns even if the specified number of acknowledgments has not been met.
239+
* @return KeyValue where Key is number of local Redises (0 or 1) that have fsynced to AOF all writes
240+
* performed in the context of the current connection, and the value is the number of replicas that have acknowledged doing the same.
241+
*/
242+
KeyValue<Long, Long> waitAOF(long numLocal, long numReplicas, long timeout);
243+
229244
String lolwut();
230245

231246
String lolwut(LolwutParams lolwutParams);

src/test/java/redis/clients/jedis/PipeliningTest.java

+13
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,19 @@ public void waitReplicas() {
468468
}
469469
}
470470

471+
@Test
472+
public void waitAof() {
473+
Pipeline p = jedis.pipelined();
474+
p.set("wait", "aof");
475+
p.waitAOF(1L, 0L, 0L);
476+
p.sync();
477+
478+
try (Jedis j = new Jedis(HostAndPorts.getRedisServers().get(4))) {
479+
j.auth("foobared");
480+
assertEquals("aof", j.get("wait"));
481+
}
482+
}
483+
471484
@Test
472485
public void setGet() {
473486
Pipeline p = jedis.pipelined();

src/test/java/redis/clients/jedis/commands/jedis/ControlCommandsTest.java

+6
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import redis.clients.jedis.exceptions.JedisDataException;
3232
import redis.clients.jedis.HostAndPorts;
3333
import redis.clients.jedis.util.AssertUtil;
34+
import redis.clients.jedis.util.KeyValue;
3435
import redis.clients.jedis.util.SafeEncoder;
3536

3637
public class ControlCommandsTest extends JedisCommandsTestBase {
@@ -248,6 +249,11 @@ public void waitReplicas() {
248249
assertEquals(1, jedis.waitReplicas(1, 100));
249250
}
250251

252+
@Test
253+
public void waitAof() {
254+
assertEquals(KeyValue.of(0L, 0L), jedis.waitAOF(0L, 0L, 100L));
255+
}
256+
251257
@Test
252258
public void clientPause() throws InterruptedException, ExecutionException {
253259
ExecutorService executorService = Executors.newFixedThreadPool(2);

src/test/java/redis/clients/jedis/modules/graph/GraphPipelineTest.java

+12
Original file line numberDiff line numberDiff line change
@@ -223,4 +223,16 @@ public void testWaitReplicas() {
223223
List<Object> results = pipeline.syncAndReturnAll();
224224
assertEquals(Long.valueOf(0), results.get(3));
225225
}
226+
227+
@Test
228+
public void testWaitAof() {
229+
Pipeline pipeline = new Pipeline(c);
230+
pipeline.set("x", "1");
231+
pipeline.graphProfile("social", "CREATE (:Person {name:'a'})");
232+
pipeline.graphProfile("g", "CREATE (:Person {name:'a'})");
233+
pipeline.waitAOF(1L, 0L, 100L);
234+
List<Object> results = pipeline.syncAndReturnAll();
235+
assertEquals(0L, results.get(3));
236+
}
237+
226238
}

0 commit comments

Comments
 (0)