From 8b7bb4de9fb423be8f462fb283e844099fb8d164 Mon Sep 17 00:00:00 2001 From: xielei Date: Sun, 26 Apr 2020 15:32:07 +0800 Subject: [PATCH 1/6] support microseconds --- .../DefaultStringRedisConnection.java | 9 +++++++++ .../connection/DefaultedRedisConnection.java | 7 +++++++ .../redis/connection/RedisServerCommands.java | 10 ++++++++++ .../redis/connection/convert/Converters.java | 6 +++--- .../jedis/JedisClusterServerCommands.java | 17 ++++++++++++++++- .../redis/connection/jedis/JedisConverters.java | 2 +- .../connection/jedis/JedisServerCommands.java | 8 ++++++++ .../lettuce/LettuceClusterServerCommands.java | 13 ++++++++++++- .../connection/lettuce/LettuceConverters.java | 2 +- .../lettuce/LettuceServerCommands.java | 8 ++++++++ 10 files changed, 75 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/springframework/data/redis/connection/DefaultStringRedisConnection.java b/src/main/java/org/springframework/data/redis/connection/DefaultStringRedisConnection.java index 7c4dc34b91..c70add4dcf 100644 --- a/src/main/java/org/springframework/data/redis/connection/DefaultStringRedisConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/DefaultStringRedisConnection.java @@ -3303,6 +3303,15 @@ public Long time() { return convertAndReturn(this.delegate.time(), identityConverter); } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisServerCommands#microseconds() + */ + @Override + public Long microseconds() { + return convertAndReturn(this.delegate.microseconds(), identityConverter); + } + /* * (non-Javadoc) * @see org.springframework.data.redis.connection.StringRedisConnection#getClientList() diff --git a/src/main/java/org/springframework/data/redis/connection/DefaultedRedisConnection.java b/src/main/java/org/springframework/data/redis/connection/DefaultedRedisConnection.java index 0cf72c98a7..d8c80598a8 100644 --- a/src/main/java/org/springframework/data/redis/connection/DefaultedRedisConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/DefaultedRedisConnection.java @@ -1394,6 +1394,13 @@ default Long time() { return serverCommands().time(); } + /** @deprecated in favor of {@link RedisConnection#serverCommands()}. */ + @Override + @Deprecated + default Long microseconds() { + return serverCommands().microseconds(); + } + /** @deprecated in favor of {@link RedisConnection#serverCommands()}. */ @Override @Deprecated diff --git a/src/main/java/org/springframework/data/redis/connection/RedisServerCommands.java b/src/main/java/org/springframework/data/redis/connection/RedisServerCommands.java index 8b5e2805e3..7164b2fcef 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisServerCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisServerCommands.java @@ -183,6 +183,16 @@ default void bgWriteAof() { @Nullable Long time(); + /** + * Request server timestamp using {@code TIME} command. + * + * @return current server time in microseconds or {@literal null} when used in pipeline / transaction. + * @since 1.1 + * @see Redis Documentation: TIME + */ + @Nullable + Long microseconds(); + /** * Closes a given client connection identified by {@literal host:port}. * diff --git a/src/main/java/org/springframework/data/redis/connection/convert/Converters.java b/src/main/java/org/springframework/data/redis/connection/convert/Converters.java index c773e8cfc3..c4a34a5eee 100644 --- a/src/main/java/org/springframework/data/redis/connection/convert/Converters.java +++ b/src/main/java/org/springframework/data/redis/connection/convert/Converters.java @@ -309,9 +309,9 @@ public static List toObjects(Set tuples) { * @param microseconds elapsed microseconds in current second * @return */ - public static Long toTimeMillis(String seconds, String microseconds) { - return NumberUtils.parseNumber(seconds, Long.class) * 1000L - + NumberUtils.parseNumber(microseconds, Long.class) / 1000L; + public static Long toTimeMicros(String seconds, String microseconds) { + return NumberUtils.parseNumber(seconds, Long.class) * 1000 * 1000L + + NumberUtils.parseNumber(microseconds, Long.class); } /** diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterServerCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterServerCommands.java index f19b36a5ab..565c5617bf 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterServerCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterServerCommands.java @@ -399,6 +399,17 @@ public Long time() { .executeCommandOnArbitraryNode((JedisClusterCommandCallback>) BinaryJedis::time).getValue()); } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisServerCommands#time() + */ + @Override + public Long microseconds() { + + return convertListOfStringToMicros(connection.getClusterCommandExecutor() + .executeCommandOnArbitraryNode((JedisClusterCommandCallback>) BinaryJedis::time).getValue()); + } + /* * (non-Javadoc) * @see org.springframework.data.redis.connection.RedisClusterServerCommands#time(org.springframework.data.redis.connection.RedisClusterNode) @@ -518,11 +529,15 @@ public void migrate(byte[] key, RedisNode target, int dbIndex, @Nullable Migrate private Long convertListOfStringToTime(List serverTimeInformation) { + return convertListOfStringToMicros(serverTimeInformation) / 1000; + } + + private Long convertListOfStringToMicros(List serverTimeInformation) { Assert.notEmpty(serverTimeInformation, "Received invalid result from server. Expected 2 items in collection."); Assert.isTrue(serverTimeInformation.size() == 2, "Received invalid number of arguments from redis server. Expected 2 received " + serverTimeInformation.size()); - return Converters.toTimeMillis(serverTimeInformation.get(0), serverTimeInformation.get(1)); + return Converters.toTimeMicros(serverTimeInformation.get(0), serverTimeInformation.get(1)); } private NodeResult executeCommandOnSingleNode(JedisClusterCommandCallback cmd, RedisClusterNode node) { diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConverters.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConverters.java index b7f00edd3f..16e16f657e 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConverters.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConverters.java @@ -193,7 +193,7 @@ public byte[] convert(SetOption source) { Assert.isTrue(source.size() == 2, "Received invalid nr of arguments from redis server. Expected 2 received " + source.size()); - return toTimeMillis(source.get(0), source.get(1)); + return toTimeMicros(source.get(0), source.get(1)); }; GEO_COORDINATE_TO_POINT_CONVERTER = geoCoordinate -> geoCoordinate != null diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisServerCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisServerCommands.java index 93fbffb605..7d0cc78129 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisServerCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisServerCommands.java @@ -353,7 +353,15 @@ public void resetConfigStats() { */ @Override public Long time() { + return microseconds() / 1000; + } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisServerCommands#time() + */ + @Override + public Long microseconds() { try { if (isPipelined()) { pipeline(connection.newJedisResult(connection.getRequiredPipeline().time(), JedisConverters.toTimeConverter())); diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterServerCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterServerCommands.java index 039534a592..7b27e9731b 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterServerCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterServerCommands.java @@ -312,7 +312,15 @@ public void resetConfigStats(RedisClusterNode node) { */ @Override public Long time() { + return microseconds() / 1000; + } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.lettuce.LettuceServerCommands#time() + */ + @Override + public Long microseconds() { return convertListOfStringToTime(connection.getClusterCommandExecutor() .executeCommandOnArbitraryNode((LettuceClusterCommandCallback>) RedisServerCommands::time) .getValue()); @@ -384,12 +392,15 @@ private MultiNodeResult executeCommandOnAllNodes(final LettuceClusterComm } private static Long convertListOfStringToTime(List serverTimeInformation) { + return convertListOfStringToMicros(serverTimeInformation) / 1000; + } + private static Long convertListOfStringToMicros(List serverTimeInformation) { Assert.notEmpty(serverTimeInformation, "Received invalid result from server. Expected 2 items in collection."); Assert.isTrue(serverTimeInformation.size() == 2, "Received invalid number of arguments from redis server. Expected 2 received " + serverTimeInformation.size()); - return Converters.toTimeMillis(LettuceConverters.toString(serverTimeInformation.get(0)), + return Converters.toTimeMicros(LettuceConverters.toString(serverTimeInformation.get(0)), LettuceConverters.toString(serverTimeInformation.get(1))); } } diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConverters.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConverters.java index 44be5a7254..53820eddcf 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConverters.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConverters.java @@ -304,7 +304,7 @@ private Set parseFlags(Set source) { Assert.isTrue(source.size() == 2, "Received invalid nr of arguments from redis server. Expected 2 received " + source.size()); - return toTimeMillis(toString(source.get(0)), toString(source.get(1))); + return toTimeMicros(toString(source.get(0)), toString(source.get(1))); }; GEO_COORDINATE_TO_POINT_CONVERTER = geoCoordinate -> geoCoordinate != null diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceServerCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceServerCommands.java index ae12e18a97..9eb7b677f8 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceServerCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceServerCommands.java @@ -361,7 +361,15 @@ public void resetConfigStats() { */ @Override public Long time() { + return microseconds() / 1000; + } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.RedisServerCommands#time() + */ + @Override + public Long microseconds() { try { if (isPipelined()) { pipeline(connection.newLettuceResult(getAsyncConnection().time(), LettuceConverters.toTimeConverter())); From f9139ae12860201ca5eee5d20fe107dcf2341173 Mon Sep 17 00:00:00 2001 From: xielei Date: Mon, 27 Apr 2020 10:45:57 +0800 Subject: [PATCH 2/6] support microseconds --- .../data/redis/connection/jedis/JedisServerCommands.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisServerCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisServerCommands.java index 7d0cc78129..4d2dde201c 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisServerCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisServerCommands.java @@ -353,7 +353,8 @@ public void resetConfigStats() { */ @Override public Long time() { - return microseconds() / 1000; + Long time = microseconds(); + return time == null ? null : time / 1000; } /* From a63183454ef1b2328d75c8c12c2549f2ff8dadfc Mon Sep 17 00:00:00 2001 From: xielei Date: Mon, 27 Apr 2020 10:59:38 +0800 Subject: [PATCH 3/6] support microseconds --- .../redis/connection/lettuce/LettuceClusterServerCommands.java | 3 ++- .../data/redis/connection/lettuce/LettuceServerCommands.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterServerCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterServerCommands.java index 7b27e9731b..12b9de6c60 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterServerCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterServerCommands.java @@ -312,7 +312,8 @@ public void resetConfigStats(RedisClusterNode node) { */ @Override public Long time() { - return microseconds() / 1000; + Long time = microseconds(); + return time == null ? null : time / 1000; } /* diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceServerCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceServerCommands.java index 9eb7b677f8..5120a00145 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceServerCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceServerCommands.java @@ -361,7 +361,8 @@ public void resetConfigStats() { */ @Override public Long time() { - return microseconds() / 1000; + Long time = microseconds(); + return time == null ? null : time / 1000; } /* From e6bbac86d84dd91e4558fe2adc33c06c14df4edc Mon Sep 17 00:00:00 2001 From: xielei Date: Mon, 27 Apr 2020 11:07:15 +0800 Subject: [PATCH 4/6] support microseconds --- .../AbstractConnectionIntegrationTests.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/test/java/org/springframework/data/redis/connection/AbstractConnectionIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/AbstractConnectionIntegrationTests.java index 0659a322c0..ab13b0385c 100644 --- a/src/test/java/org/springframework/data/redis/connection/AbstractConnectionIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/AbstractConnectionIntegrationTests.java @@ -2077,6 +2077,17 @@ public void testGetTimeShouldRequestServerTime() { assertThat((Long) results.get(0) > 0).isTrue(); } + @Test + public void testGetMicrosecondsShouldRequestServerTime() { + + actual.add(connection.microseconds()); + + List results = getResults(); + assertThat(results).isNotEmpty(); + assertThat(results.get(0)).isNotNull(); + assertThat((Long) results.get(0) > 0).isTrue(); + } + @Test // DATAREDIS-269 public void clientSetNameWorksCorrectly() { connection.setClientName("foo".getBytes()); From bc57a78327d2dbac789b06a79dbce21e20dd3a06 Mon Sep 17 00:00:00 2001 From: xielei Date: Tue, 10 Nov 2020 14:09:41 +0800 Subject: [PATCH 5/6] support microseconds --- .../data/redis/connection/convert/Converters.java | 11 +++++++++++ .../connection/jedis/JedisClusterServerCommands.java | 4 ++-- .../redis/connection/jedis/JedisServerCommands.java | 3 ++- .../lettuce/LettuceClusterServerCommands.java | 3 ++- .../connection/lettuce/LettuceServerCommands.java | 3 ++- 5 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/springframework/data/redis/connection/convert/Converters.java b/src/main/java/org/springframework/data/redis/connection/convert/Converters.java index c4a34a5eee..2ef4b5af07 100644 --- a/src/main/java/org/springframework/data/redis/connection/convert/Converters.java +++ b/src/main/java/org/springframework/data/redis/connection/convert/Converters.java @@ -314,6 +314,17 @@ public static Long toTimeMicros(String seconds, String microseconds) { + NumberUtils.parseNumber(microseconds, Long.class); } + /** + * Returns the timestamp constructed from the given {@code seconds} and {@code microseconds}. + * + * @param seconds server time in seconds + * @param microseconds elapsed microseconds in current second + * @return + */ + public static Long toTimeMillis(String seconds, String microseconds) { + return NumberUtils.parseNumber(seconds, Long.class) * 1000L + + NumberUtils.parseNumber(microseconds, Long.class) / 1000L; + } /** * Converts {@code seconds} to the given {@link TimeUnit}. * diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterServerCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterServerCommands.java index 565c5617bf..edc544ffee 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterServerCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterServerCommands.java @@ -26,6 +26,7 @@ import java.util.List; import java.util.Map.Entry; import java.util.Properties; +import java.util.concurrent.TimeUnit; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.ClusterCommandExecutor.MultiNodeResult; @@ -528,8 +529,7 @@ public void migrate(byte[] key, RedisNode target, int dbIndex, @Nullable Migrate } private Long convertListOfStringToTime(List serverTimeInformation) { - - return convertListOfStringToMicros(serverTimeInformation) / 1000; + return TimeUnit.MICROSECONDS.toMillis(convertListOfStringToMicros(serverTimeInformation)); } private Long convertListOfStringToMicros(List serverTimeInformation) { diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisServerCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisServerCommands.java index 4d2dde201c..02243d3905 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisServerCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisServerCommands.java @@ -20,6 +20,7 @@ import java.util.List; import java.util.Properties; +import java.util.concurrent.TimeUnit; import org.springframework.data.redis.connection.RedisNode; import org.springframework.data.redis.connection.RedisServerCommands; @@ -354,7 +355,7 @@ public void resetConfigStats() { @Override public Long time() { Long time = microseconds(); - return time == null ? null : time / 1000; + return time == null ? null : TimeUnit.MICROSECONDS.toMillis(time); } /* diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterServerCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterServerCommands.java index 12b9de6c60..3a5474d2d9 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterServerCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterServerCommands.java @@ -23,6 +23,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Properties; +import java.util.concurrent.TimeUnit; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.ClusterCommandExecutor.MultiNodeResult; @@ -313,7 +314,7 @@ public void resetConfigStats(RedisClusterNode node) { @Override public Long time() { Long time = microseconds(); - return time == null ? null : time / 1000; + return time == null ? null : TimeUnit.MICROSECONDS.toMillis(time); } /* diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceServerCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceServerCommands.java index 5120a00145..7df3f09576 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceServerCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceServerCommands.java @@ -22,6 +22,7 @@ import java.util.List; import java.util.Properties; +import java.util.concurrent.TimeUnit; import org.springframework.dao.DataAccessException; import org.springframework.data.redis.connection.RedisNode; @@ -362,7 +363,7 @@ public void resetConfigStats() { @Override public Long time() { Long time = microseconds(); - return time == null ? null : time / 1000; + return time == null ? null : TimeUnit.MICROSECONDS.toMillis(time); } /* From ce63db80dd9895dc311708be6c8b0d8882df1aca Mon Sep 17 00:00:00 2001 From: xielei Date: Tue, 10 Nov 2020 14:11:37 +0800 Subject: [PATCH 6/6] support microseconds --- .../data/redis/connection/convert/Converters.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/springframework/data/redis/connection/convert/Converters.java b/src/main/java/org/springframework/data/redis/connection/convert/Converters.java index 2ef4b5af07..1e8780f729 100644 --- a/src/main/java/org/springframework/data/redis/connection/convert/Converters.java +++ b/src/main/java/org/springframework/data/redis/connection/convert/Converters.java @@ -310,7 +310,7 @@ public static List toObjects(Set tuples) { * @return */ public static Long toTimeMicros(String seconds, String microseconds) { - return NumberUtils.parseNumber(seconds, Long.class) * 1000 * 1000L + return TimeUnit.SECONDS.toMicros(NumberUtils.parseNumber(seconds, Long.class)) + NumberUtils.parseNumber(microseconds, Long.class); }