Skip to content

Commit 102ee01

Browse files
committed
Add support for microseconds using TIME.
Closes #526. Original pull request: #526.
1 parent 773acd0 commit 102ee01

17 files changed

+154
-47
lines changed

src/main/java/org/springframework/data/redis/connection/DefaultStringRedisConnection.java

+9
Original file line numberDiff line numberDiff line change
@@ -3353,6 +3353,15 @@ public Long time() {
33533353
return convertAndReturn(this.delegate.time(), Converters.identityConverter());
33543354
}
33553355

3356+
/*
3357+
* (non-Javadoc)
3358+
* @see org.springframework.data.redis.connection.RedisServerCommands#time(TimeUnit)
3359+
*/
3360+
@Override
3361+
public Long time(TimeUnit timeUnit) {
3362+
return convertAndReturn(this.delegate.time(timeUnit), Converters.identityConverter());
3363+
}
3364+
33563365
/*
33573366
* (non-Javadoc)
33583367
* @see org.springframework.data.redis.connection.StringRedisConnection#getClientList()

src/main/java/org/springframework/data/redis/connection/DefaultedRedisClusterConnection.java

+8
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import java.util.Collection;
1919
import java.util.List;
2020
import java.util.Properties;
21+
import java.util.concurrent.TimeUnit;
2122

2223
import org.springframework.data.redis.core.types.RedisClientInfo;
2324
import org.springframework.lang.Nullable;
@@ -128,6 +129,13 @@ default Long time(RedisClusterNode node) {
128129
return serverCommands().time(node);
129130
}
130131

132+
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
133+
@Override
134+
@Deprecated
135+
default Long time(RedisClusterNode node, TimeUnit timeUnit) {
136+
return serverCommands().time(node, timeUnit);
137+
}
138+
131139
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
132140
@Override
133141
@Deprecated

src/main/java/org/springframework/data/redis/connection/DefaultedRedisConnection.java

+7
Original file line numberDiff line numberDiff line change
@@ -1437,6 +1437,13 @@ default Long time() {
14371437
return serverCommands().time();
14381438
}
14391439

1440+
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
1441+
@Override
1442+
@Deprecated
1443+
default Long time(TimeUnit timeUnit) {
1444+
return serverCommands().time(timeUnit);
1445+
}
1446+
14401447
/** @deprecated in favor of {@link RedisConnection#serverCommands()}. */
14411448
@Override
14421449
@Deprecated

src/main/java/org/springframework/data/redis/connection/ReactiveServerCommands.java

+15-2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import reactor.core.publisher.Mono;
2020

2121
import java.util.Properties;
22+
import java.util.concurrent.TimeUnit;
2223

2324
import org.springframework.data.redis.core.types.RedisClientInfo;
2425

@@ -142,12 +143,24 @@ public interface ReactiveServerCommands {
142143
Mono<String> resetConfigStats();
143144

144145
/**
145-
* Request server timestamp using {@code TIME} command.
146+
* Request server timestamp using {@code TIME} command in {@link TimeUnit#MILLISECONDS}.
146147
*
147148
* @return {@link Mono} wrapping current server time in milliseconds.
148149
* @see <a href="https://redis.io/commands/time">Redis Documentation: TIME</a>
149150
*/
150-
Mono<Long> time();
151+
default Mono<Long> time() {
152+
return time(TimeUnit.MILLISECONDS);
153+
}
154+
155+
/**
156+
* Request server timestamp using {@code TIME} command.
157+
*
158+
* @param timeUnit target unit.
159+
* @return {@link Mono} wrapping current server time in {@link TimeUnit}.
160+
* @since 2.5
161+
* @see <a href="https://redis.io/commands/time">Redis Documentation: TIME</a>
162+
*/
163+
Mono<Long> time(TimeUnit timeUnit);
151164

152165
/**
153166
* Closes a given client connection identified by {@literal host:port}.

src/main/java/org/springframework/data/redis/connection/RedisClusterServerCommands.java

+13-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import java.util.List;
1919
import java.util.Properties;
20+
import java.util.concurrent.TimeUnit;
2021

2122
import org.springframework.data.redis.core.types.RedisClientInfo;
2223

@@ -118,7 +119,18 @@ public interface RedisClusterServerCommands extends RedisServerCommands {
118119
* @return
119120
* @see RedisServerCommands#time()
120121
*/
121-
Long time(RedisClusterNode node);
122+
default Long time(RedisClusterNode node) {
123+
return time(node, TimeUnit.MILLISECONDS);
124+
}
125+
126+
/**
127+
* @param node must not be {@literal null}.
128+
* @param timeUnit must not be {@literal null}.
129+
* @return
130+
* @since 2.5
131+
* @see RedisServerCommands#time(TimeUnit)
132+
*/
133+
Long time(RedisClusterNode node, TimeUnit timeUnit);
122134

123135
/**
124136
* @param node must not be {@literal null}.

src/main/java/org/springframework/data/redis/connection/RedisServerCommands.java

+16-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import java.util.List;
1919
import java.util.Properties;
20+
import java.util.concurrent.TimeUnit;
2021

2122
import org.springframework.data.redis.core.types.RedisClientInfo;
2223
import org.springframework.lang.Nullable;
@@ -174,14 +175,27 @@ default void bgWriteAof() {
174175
void resetConfigStats();
175176

176177
/**
177-
* Request server timestamp using {@code TIME} command.
178+
* Request server timestamp using {@code TIME} command in {@link TimeUnit#MILLISECONDS}.
178179
*
179180
* @return current server time in milliseconds or {@literal null} when used in pipeline / transaction.
180181
* @since 1.1
181182
* @see <a href="https://redis.io/commands/time">Redis Documentation: TIME</a>
182183
*/
183184
@Nullable
184-
Long time();
185+
default Long time() {
186+
return time(TimeUnit.MILLISECONDS);
187+
}
188+
189+
/**
190+
* Request server timestamp using {@code TIME} command.
191+
*
192+
* @param timeUnit target unit.
193+
* @return current server time in {@link TimeUnit} or {@literal null} when used in pipeline / transaction.
194+
* @since 2.5
195+
* @see <a href="https://redis.io/commands/time">Redis Documentation: TIME</a>
196+
*/
197+
@Nullable
198+
Long time(TimeUnit timeUnit);
185199

186200
/**
187201
* Closes a given client connection identified by {@literal host:port}.

src/main/java/org/springframework/data/redis/connection/convert/Converters.java

+17
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,23 @@ public static Long toTimeMillis(String seconds, String microseconds) {
207207
+ NumberUtils.parseNumber(microseconds, Long.class) / 1000L;
208208
}
209209

210+
/**
211+
* Returns the timestamp constructed from the given {@code seconds} and {@code microseconds}.
212+
*
213+
* @param seconds server time in seconds.
214+
* @param microseconds elapsed microseconds in current second.
215+
* @param unit target unit.
216+
* @return
217+
* @since 2.5
218+
*/
219+
public static Long toTimeMillis(String seconds, String microseconds, TimeUnit unit) {
220+
221+
long secondValue = TimeUnit.SECONDS.toMicros(NumberUtils.parseNumber(seconds, Long.class));
222+
long microValue = NumberUtils.parseNumber(microseconds, Long.class);
223+
224+
return unit.convert(secondValue + microValue, TimeUnit.MICROSECONDS);
225+
}
226+
210227
/**
211228
* Converts {@code seconds} to the given {@link TimeUnit}.
212229
*

src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterServerCommands.java

+11-8
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.util.List;
2525
import java.util.Map.Entry;
2626
import java.util.Properties;
27+
import java.util.concurrent.TimeUnit;
2728

2829
import org.springframework.dao.InvalidDataAccessApiUsageException;
2930
import org.springframework.data.redis.connection.ClusterCommandExecutor.MultiNodeResult;
@@ -391,24 +392,26 @@ public void resetConfigStats(RedisClusterNode node) {
391392

392393
/*
393394
* (non-Javadoc)
394-
* @see org.springframework.data.redis.connection.RedisServerCommands#time()
395+
* @see org.springframework.data.redis.connection.RedisServerCommands#time(TimeUnit)
395396
*/
396397
@Override
397-
public Long time() {
398+
public Long time(TimeUnit timeUnit) {
398399

399400
return convertListOfStringToTime(connection.getClusterCommandExecutor()
400-
.executeCommandOnArbitraryNode((JedisClusterCommandCallback<List<String>>) BinaryJedis::time).getValue());
401+
.executeCommandOnArbitraryNode((JedisClusterCommandCallback<List<String>>) BinaryJedis::time).getValue(),
402+
timeUnit);
401403
}
402404

403405
/*
404406
* (non-Javadoc)
405-
* @see org.springframework.data.redis.connection.RedisClusterServerCommands#time(org.springframework.data.redis.connection.RedisClusterNode)
407+
* @see org.springframework.data.redis.connection.RedisClusterServerCommands#time(org.springframework.data.redis.connection.RedisClusterNode, TimeUnit)
406408
*/
407409
@Override
408-
public Long time(RedisClusterNode node) {
410+
public Long time(RedisClusterNode node, TimeUnit timeUnit) {
409411

410412
return convertListOfStringToTime(connection.getClusterCommandExecutor()
411-
.executeCommandOnSingleNode((JedisClusterCommandCallback<List<String>>) BinaryJedis::time, node).getValue());
413+
.executeCommandOnSingleNode((JedisClusterCommandCallback<List<String>>) BinaryJedis::time, node).getValue(),
414+
timeUnit);
412415
}
413416

414417
/*
@@ -517,13 +520,13 @@ public void migrate(byte[] key, RedisNode target, int dbIndex, @Nullable Migrate
517520
node);
518521
}
519522

520-
private Long convertListOfStringToTime(List<String> serverTimeInformation) {
523+
private Long convertListOfStringToTime(List<String> serverTimeInformation, TimeUnit timeUnit) {
521524

522525
Assert.notEmpty(serverTimeInformation, "Received invalid result from server. Expected 2 items in collection.");
523526
Assert.isTrue(serverTimeInformation.size() == 2,
524527
"Received invalid number of arguments from redis server. Expected 2 received " + serverTimeInformation.size());
525528

526-
return Converters.toTimeMillis(serverTimeInformation.get(0), serverTimeInformation.get(1));
529+
return Converters.toTimeMillis(serverTimeInformation.get(0), serverTimeInformation.get(1), timeUnit);
527530
}
528531

529532
private <T> NodeResult<T> executeCommandOnSingleNode(JedisClusterCommandCallback<T> cmd, RedisClusterNode node) {

src/main/java/org/springframework/data/redis/connection/jedis/JedisConverters.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -547,13 +547,14 @@ public static ScanParams toScanParams(ScanOptions options) {
547547
return sp;
548548
}
549549

550-
static Long toTime(List<String> source) {
550+
static Long toTime(List<String> source, TimeUnit timeUnit) {
551551

552552
Assert.notEmpty(source, "Received invalid result from server. Expected 2 items in collection.");
553553
Assert.isTrue(source.size() == 2,
554554
"Received invalid nr of arguments from redis server. Expected 2 received " + source.size());
555+
Assert.notNull(timeUnit, "TimeUnit must not be null.");
555556

556-
return toTimeMillis(source.get(0), source.get(1));
557+
return toTimeMillis(source.get(0), source.get(1), timeUnit);
557558
}
558559

559560
/**

src/main/java/org/springframework/data/redis/connection/jedis/JedisServerCommands.java

+7-3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import java.util.List;
2323
import java.util.Properties;
24+
import java.util.concurrent.TimeUnit;
2425

2526
import org.springframework.data.redis.connection.RedisNode;
2627
import org.springframework.data.redis.connection.RedisServerCommands;
@@ -190,12 +191,15 @@ public void resetConfigStats() {
190191

191192
/*
192193
* (non-Javadoc)
193-
* @see org.springframework.data.redis.connection.RedisServerCommands#time()
194+
* @see org.springframework.data.redis.connection.RedisServerCommands#time(TimeUnit)
194195
*/
195196
@Override
196-
public Long time() {
197+
public Long time(TimeUnit timeUnit) {
198+
199+
Assert.notNull(timeUnit, "TimeUnit must not be null.");
200+
197201
return connection.invoke().from(BinaryJedis::time, MultiKeyPipelineBase::time)
198-
.get(JedisConverters::toTime);
202+
.get((List<String> source) -> JedisConverters.toTime(source, timeUnit));
199203
}
200204

201205
/*

src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterServerCommands.java

+5-16
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.Map;
2424
import java.util.Map.Entry;
2525
import java.util.Properties;
26+
import java.util.concurrent.TimeUnit;
2627

2728
import org.springframework.dao.InvalidDataAccessApiUsageException;
2829
import org.springframework.data.redis.connection.ClusterCommandExecutor.MultiNodeResult;
@@ -306,25 +307,13 @@ public void resetConfigStats(RedisClusterNode node) {
306307
executeCommandOnSingleNode(RedisServerCommands::configResetstat, node);
307308
}
308309

309-
/*
310-
* (non-Javadoc)
311-
* @see org.springframework.data.redis.connection.lettuce.LettuceServerCommands#time()
312-
*/
313-
@Override
314-
public Long time() {
315-
316-
return convertListOfStringToTime(connection.getClusterCommandExecutor()
317-
.executeCommandOnArbitraryNode((LettuceClusterCommandCallback<List<byte[]>>) RedisServerCommands::time)
318-
.getValue());
319-
}
320-
321310
/*
322311
* (non-Javadoc)
323312
* @see org.springframework.data.redis.connection.RedisClusterServerCommands#time(org.springframework.data.redis.connection.RedisClusterNode)
324313
*/
325314
@Override
326-
public Long time(RedisClusterNode node) {
327-
return convertListOfStringToTime(executeCommandOnSingleNode(RedisServerCommands::time, node).getValue());
315+
public Long time(RedisClusterNode node, TimeUnit timeUnit) {
316+
return convertListOfStringToTime(executeCommandOnSingleNode(RedisServerCommands::time, node).getValue(), timeUnit);
328317
}
329318

330319
/*
@@ -383,13 +372,13 @@ private <T> MultiNodeResult<T> executeCommandOnAllNodes(final LettuceClusterComm
383372
return connection.getClusterCommandExecutor().executeCommandOnAllNodes(cmd);
384373
}
385374

386-
private static Long convertListOfStringToTime(List<byte[]> serverTimeInformation) {
375+
private static Long convertListOfStringToTime(List<byte[]> serverTimeInformation, TimeUnit timeUnit) {
387376

388377
Assert.notEmpty(serverTimeInformation, "Received invalid result from server. Expected 2 items in collection.");
389378
Assert.isTrue(serverTimeInformation.size() == 2,
390379
"Received invalid number of arguments from redis server. Expected 2 received " + serverTimeInformation.size());
391380

392381
return Converters.toTimeMillis(LettuceConverters.toString(serverTimeInformation.get(0)),
393-
LettuceConverters.toString(serverTimeInformation.get(1)));
382+
LettuceConverters.toString(serverTimeInformation.get(1)), timeUnit);
394383
}
395384
}

src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConverters.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -725,15 +725,15 @@ public static SetArgs toSetArgs(@Nullable Expiration expiration, @Nullable SetOp
725725
return args;
726726
}
727727

728-
static Converter<List<byte[]>, Long> toTimeConverter() {
728+
static Converter<List<byte[]>, Long> toTimeConverter(TimeUnit timeUnit) {
729729

730730
return source -> {
731731

732732
Assert.notEmpty(source, "Received invalid result from server. Expected 2 items in collection.");
733733
Assert.isTrue(source.size() == 2,
734734
"Received invalid nr of arguments from redis server. Expected 2 received " + source.size());
735735

736-
return toTimeMillis(toString(source.get(0)), toString(source.get(1)));
736+
return toTimeMillis(toString(source.get(0)), toString(source.get(1)), timeUnit);
737737
};
738738
}
739739

src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveClusterServerCommands.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import java.util.Map.Entry;
3131
import java.util.Properties;
3232
import java.util.Set;
33+
import java.util.concurrent.TimeUnit;
3334
import java.util.function.BiConsumer;
3435
import java.util.function.BinaryOperator;
3536
import java.util.function.Function;
@@ -260,7 +261,7 @@ public Mono<Long> time(RedisClusterNode node) {
260261
return connection.execute(node, RedisServerReactiveCommands::time) //
261262
.map(ByteUtils::getBytes) //
262263
.collectList() //
263-
.map(LettuceConverters.toTimeConverter()::convert);
264+
.map(LettuceConverters.toTimeConverter(TimeUnit.MILLISECONDS)::convert);
264265
}
265266

266267
/*

src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveServerCommands.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.nio.ByteBuffer;
2323
import java.util.Date;
2424
import java.util.Properties;
25+
import java.util.concurrent.TimeUnit;
2526

2627
import org.springframework.data.redis.connection.ReactiveServerCommands;
2728
import org.springframework.data.redis.core.types.RedisClientInfo;
@@ -177,15 +178,15 @@ public Mono<String> resetConfigStats() {
177178

178179
/*
179180
* (non-Javadoc)
180-
* @see org.springframework.data.redis.connection.ReactiveServerCommands#time()
181+
* @see org.springframework.data.redis.connection.ReactiveServerCommands#time(TimeUnit)
181182
*/
182183
@Override
183-
public Mono<Long> time() {
184+
public Mono<Long> time(TimeUnit timeUnit) {
184185

185186
return connection.execute(RedisServerReactiveCommands::time) //
186187
.map(ByteUtils::getBytes) //
187188
.collectList() //
188-
.map(LettuceConverters.toTimeConverter()::convert);
189+
.map(LettuceConverters.toTimeConverter(timeUnit)::convert);
189190
}
190191

191192
/*

0 commit comments

Comments
 (0)