From 6f887a44b63f2b89a49084abc2136690b75ee7a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Slowik?= Date: Tue, 19 Oct 2021 11:43:06 +0200 Subject: [PATCH 01/58] Added new SMISMEMBER command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bartłomiej Slowik --- .../main/java/org/redisson/RedissonSet.java | 19 +++++++++++ .../redisson/RedissonSetMultimapValues.java | 10 ++++++ .../src/main/java/org/redisson/api/RSet.java | 10 ++++++ .../main/java/org/redisson/api/RSetAsync.java | 10 ++++++ .../client/protocol/RedisCommands.java | 1 + .../java/org/redisson/RedissonSetTest.java | 33 +++++++++++++++---- 6 files changed, 77 insertions(+), 6 deletions(-) diff --git a/redisson/src/main/java/org/redisson/RedissonSet.java b/redisson/src/main/java/org/redisson/RedissonSet.java index 03109c507..754a0512c 100644 --- a/redisson/src/main/java/org/redisson/RedissonSet.java +++ b/redisson/src/main/java/org/redisson/RedissonSet.java @@ -321,6 +321,20 @@ public class RedissonSet extends RedissonExpirable implements RSet, ScanIt return commandExecutor.writeAsync(getRawName(), codec, RedisCommands.SREM, args.toArray()); } + @Override + public RFuture> containsEachAsync(Collection c) { + if (c.isEmpty()) { + return RedissonPromise.newSucceededFuture(Collections.emptyList()); + } + + List args = new ArrayList(c.size() + 1); + args.add(getRawName()); + encode(args, c); + + return commandExecutor.readAsync(getRawName(), codec, RedisCommands.SMISMEMBER, args.toArray()); + + } + @Override public boolean removeAll(Collection c) { return get(removeAllAsync(c)); @@ -635,6 +649,11 @@ public class RedissonSet extends RedissonExpirable implements RSet, ScanIt return get(tryAddAsync(values)); } + @Override + public List containsEach(Collection c) { + return get(containsEachAsync(c)); + } + @Override public RFuture tryAddAsync(V... values) { return commandExecutor.evalWriteAsync(getRawName(), codec, RedisCommands.EVAL_BOOLEAN, diff --git a/redisson/src/main/java/org/redisson/RedissonSetMultimapValues.java b/redisson/src/main/java/org/redisson/RedissonSetMultimapValues.java index b2c6af4d1..dd2edefe3 100644 --- a/redisson/src/main/java/org/redisson/RedissonSetMultimapValues.java +++ b/redisson/src/main/java/org/redisson/RedissonSetMultimapValues.java @@ -80,6 +80,11 @@ public class RedissonSetMultimapValues extends RedissonExpirable implements R return get(tryAddAsync(values)); } + @Override + public List containsEach(Collection c) { + throw new UnsupportedOperationException("This operation is not supported for SetMultimap values"); + } + @Override public RFuture tryAddAsync(V... values) { return set.tryAddAsync(values); @@ -439,6 +444,11 @@ public class RedissonSetMultimapValues extends RedissonExpirable implements R throw new UnsupportedOperationException("This operation is not supported for SetMultimap values"); } + @Override + public RFuture> containsEachAsync(Collection c) { + throw new UnsupportedOperationException("This operation is not supported for SetMultimap values"); + } + @Override public boolean retainAll(Collection c) { return get(retainAllAsync(c)); diff --git a/redisson/src/main/java/org/redisson/api/RSet.java b/redisson/src/main/java/org/redisson/api/RSet.java index 461276990..1e68daa53 100644 --- a/redisson/src/main/java/org/redisson/api/RSet.java +++ b/redisson/src/main/java/org/redisson/api/RSet.java @@ -19,6 +19,7 @@ import org.redisson.api.mapreduce.RCollectionMapReduce; import java.util.Collection; import java.util.Iterator; +import java.util.List; import java.util.Set; import java.util.stream.Stream; @@ -274,4 +275,13 @@ public interface RSet extends Set, RExpirable, RSetAsync, RSortable containsEach(Collection c); + } diff --git a/redisson/src/main/java/org/redisson/api/RSetAsync.java b/redisson/src/main/java/org/redisson/api/RSetAsync.java index 56f78dac0..bb1f0a2a7 100644 --- a/redisson/src/main/java/org/redisson/api/RSetAsync.java +++ b/redisson/src/main/java/org/redisson/api/RSetAsync.java @@ -16,6 +16,7 @@ package org.redisson.api; import java.util.Collection; +import java.util.List; import java.util.Set; /** @@ -158,4 +159,13 @@ public interface RSetAsync extends RCollectionAsync, RSortableAsync */ RFuture removeAllCountedAsync(Collection c); + /** + * Check if each element is contained in the specified collection. + * Returns whether each element is a member of the specified collection. + * + * @param c - collection of elements to check + * @return whether each element is a member of the specified collection + */ + RFuture> containsEachAsync(Collection c); + } diff --git a/redisson/src/main/java/org/redisson/client/protocol/RedisCommands.java b/redisson/src/main/java/org/redisson/client/protocol/RedisCommands.java index 05c67d7ef..23e08cf6f 100644 --- a/redisson/src/main/java/org/redisson/client/protocol/RedisCommands.java +++ b/redisson/src/main/java/org/redisson/client/protocol/RedisCommands.java @@ -165,6 +165,7 @@ public interface RedisCommands { RedisCommand> SUNION = new RedisCommand>("SUNION", new ObjectSetReplayDecoder()); RedisCommand> SDIFF = new RedisCommand>("SDIFF", new ObjectSetReplayDecoder()); RedisCommand> SINTER = new RedisCommand>("SINTER", new ObjectSetReplayDecoder()); + RedisCommand> SMISMEMBER = new RedisCommand>("SMISMEMBER", new ObjectListReplayDecoder()); RedisStrictCommand LPOS = new RedisStrictCommand<>("LPOS"); RedisCommand LSET = new RedisCommand("LSET", new VoidReplayConvertor()); diff --git a/redisson/src/test/java/org/redisson/RedissonSetTest.java b/redisson/src/test/java/org/redisson/RedissonSetTest.java index b82f8bd0f..e46611594 100644 --- a/redisson/src/test/java/org/redisson/RedissonSetTest.java +++ b/redisson/src/test/java/org/redisson/RedissonSetTest.java @@ -4,14 +4,10 @@ import static org.assertj.core.api.Assertions.assertThat; import java.io.IOException; import java.io.Serializable; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; +import java.util.*; import java.util.concurrent.ExecutionException; +import org.assertj.core.api.ListAssert; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.redisson.ClusterRunner.ClusterProcesses; @@ -22,6 +18,7 @@ import org.redisson.api.RSet; import org.redisson.api.RedissonClient; import org.redisson.api.SortOrder; import org.redisson.client.codec.IntegerCodec; +import org.redisson.client.codec.LongCodec; import org.redisson.client.codec.StringCodec; import org.redisson.config.Config; import org.redisson.connection.balancer.RandomLoadBalancer; @@ -42,6 +39,30 @@ public class RedissonSetTest extends BaseTest { } + @Test + public void testContainsEach() { + RSet set = redisson.getSet("list", LongCodec.INSTANCE); + set.add(0L); + set.add(1L); + + assertThat(set.containsEach(Collections.emptyList())).isEmpty(); + assertThat(set.containsEach(Arrays.asList(0L, 1L))) + .hasSize(2) + .isEqualTo(Arrays.asList(1L, 1L)); + + assertThat(set.containsEach(Arrays.asList(0L, 1L, 2L))) + .hasSize(3) + .isEqualTo(Arrays.asList(1L, 1L, 0L)); + + assertThat(set.containsEach(Arrays.asList(0L, 1L, 0L))) + .hasSize(3) + .isEqualTo(Arrays.asList(1L, 1L, 1L)); + + assertThat(set.containsEach(Arrays.asList(2L, 3L, 4L))) + .hasSize(3) + .isEqualTo(Arrays.asList(0L, 0L, 0L)); + } + @Test public void testRemoveAllCounted() { RSet set = redisson.getSet("list", IntegerCodec.INSTANCE); From 7622d131908b7a3c58e9b9a30b40da32fc5eedd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Slowik?= Date: Fri, 22 Oct 2021 19:49:08 +0200 Subject: [PATCH 02/58] Implementation return contained elements now. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bartłomiej Slowik --- .../main/java/org/redisson/RedissonSet.java | 25 +++++++++++++---- .../redisson/RedissonSetMultimapValues.java | 4 +-- .../src/main/java/org/redisson/api/RSet.java | 8 +++--- .../main/java/org/redisson/api/RSetAsync.java | 8 +++--- .../java/org/redisson/RedissonSetTest.java | 27 +++++++++---------- 5 files changed, 43 insertions(+), 29 deletions(-) diff --git a/redisson/src/main/java/org/redisson/RedissonSet.java b/redisson/src/main/java/org/redisson/RedissonSet.java index 754a0512c..04d276e87 100644 --- a/redisson/src/main/java/org/redisson/RedissonSet.java +++ b/redisson/src/main/java/org/redisson/RedissonSet.java @@ -23,6 +23,7 @@ import org.redisson.client.protocol.RedisCommands; import org.redisson.command.CommandAsyncExecutor; import org.redisson.iterator.RedissonBaseIterator; import org.redisson.mapreduce.RedissonCollectionMapReduce; +import org.redisson.misc.RPromise; import org.redisson.misc.RedissonPromise; import java.util.*; @@ -322,17 +323,31 @@ public class RedissonSet extends RedissonExpirable implements RSet, ScanIt } @Override - public RFuture> containsEachAsync(Collection c) { + public RFuture> containsEachAsync(Collection c) { if (c.isEmpty()) { return RedissonPromise.newSucceededFuture(Collections.emptyList()); } - List args = new ArrayList(c.size() + 1); args.add(getRawName()); encode(args, c); - return commandExecutor.readAsync(getRawName(), codec, RedisCommands.SMISMEMBER, args.toArray()); - + RFuture> future = commandExecutor.readAsync(getRawName(), codec, RedisCommands.SMISMEMBER, args.toArray()); + List keysToCheck = new ArrayList<>(c); + RPromise> result = new RedissonPromise<>(); + future.onComplete((res, e) -> { + if (e != null) { + result.tryFailure(e); + return; + } + List containedKeys = new ArrayList<>(); + for (int i = 0; i < res.size(); i++) { + if (res.get(i) == 1) { + containedKeys.add(keysToCheck.get(i)); + } + } + result.trySuccess(containedKeys); + }); + return result; } @Override @@ -650,7 +665,7 @@ public class RedissonSet extends RedissonExpirable implements RSet, ScanIt } @Override - public List containsEach(Collection c) { + public List containsEach(Collection c) { return get(containsEachAsync(c)); } diff --git a/redisson/src/main/java/org/redisson/RedissonSetMultimapValues.java b/redisson/src/main/java/org/redisson/RedissonSetMultimapValues.java index dd2edefe3..cc77ef805 100644 --- a/redisson/src/main/java/org/redisson/RedissonSetMultimapValues.java +++ b/redisson/src/main/java/org/redisson/RedissonSetMultimapValues.java @@ -81,7 +81,7 @@ public class RedissonSetMultimapValues extends RedissonExpirable implements R } @Override - public List containsEach(Collection c) { + public List containsEach(Collection c) { throw new UnsupportedOperationException("This operation is not supported for SetMultimap values"); } @@ -445,7 +445,7 @@ public class RedissonSetMultimapValues extends RedissonExpirable implements R } @Override - public RFuture> containsEachAsync(Collection c) { + public RFuture> containsEachAsync(Collection c) { throw new UnsupportedOperationException("This operation is not supported for SetMultimap values"); } diff --git a/redisson/src/main/java/org/redisson/api/RSet.java b/redisson/src/main/java/org/redisson/api/RSet.java index 1e68daa53..c3c904a93 100644 --- a/redisson/src/main/java/org/redisson/api/RSet.java +++ b/redisson/src/main/java/org/redisson/api/RSet.java @@ -277,11 +277,11 @@ public interface RSet extends Set, RExpirable, RSetAsync, RSortable containsEach(Collection c); + List containsEach(Collection c); } diff --git a/redisson/src/main/java/org/redisson/api/RSetAsync.java b/redisson/src/main/java/org/redisson/api/RSetAsync.java index bb1f0a2a7..c4831d99b 100644 --- a/redisson/src/main/java/org/redisson/api/RSetAsync.java +++ b/redisson/src/main/java/org/redisson/api/RSetAsync.java @@ -161,11 +161,11 @@ public interface RSetAsync extends RCollectionAsync, RSortableAsync /** * Check if each element is contained in the specified collection. - * Returns whether each element is a member of the specified collection. + * Returns contained elements. * - * @param c - collection of elements to check - * @return whether each element is a member of the specified collection + * @param c - collection to check + * @return contained elements */ - RFuture> containsEachAsync(Collection c); + RFuture> containsEachAsync(Collection c); } diff --git a/redisson/src/test/java/org/redisson/RedissonSetTest.java b/redisson/src/test/java/org/redisson/RedissonSetTest.java index e46611594..72468e7b9 100644 --- a/redisson/src/test/java/org/redisson/RedissonSetTest.java +++ b/redisson/src/test/java/org/redisson/RedissonSetTest.java @@ -41,26 +41,25 @@ public class RedissonSetTest extends BaseTest { @Test public void testContainsEach() { - RSet set = redisson.getSet("list", LongCodec.INSTANCE); - set.add(0L); - set.add(1L); + RSet set = redisson.getSet("list", IntegerCodec.INSTANCE); + set.add(0); + set.add(1); - assertThat(set.containsEach(Collections.emptyList())).isEmpty(); - assertThat(set.containsEach(Arrays.asList(0L, 1L))) + assertThat(set.containsEach(Collections.emptySet())).isEmpty(); + assertThat(set.containsEach(Arrays.asList(0, 1))) .hasSize(2) - .isEqualTo(Arrays.asList(1L, 1L)); + .containsOnly(0, 1); - assertThat(set.containsEach(Arrays.asList(0L, 1L, 2L))) - .hasSize(3) - .isEqualTo(Arrays.asList(1L, 1L, 0L)); + assertThat(set.containsEach(Arrays.asList(0, 1, 2))) + .hasSize(2) + .containsOnly(0, 1); - assertThat(set.containsEach(Arrays.asList(0L, 1L, 0L))) + assertThat(set.containsEach(Arrays.asList(0, 1, 0, 2))) .hasSize(3) - .isEqualTo(Arrays.asList(1L, 1L, 1L)); + .containsOnly(0, 1, 0); - assertThat(set.containsEach(Arrays.asList(2L, 3L, 4L))) - .hasSize(3) - .isEqualTo(Arrays.asList(0L, 0L, 0L)); + assertThat(set.containsEach(Arrays.asList(2, 3, 4))) + .hasSize(0); } @Test From 2ec5b52e7ebed064c29f8127509283b5f073d25e Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Tue, 6 Dec 2022 08:31:35 +0300 Subject: [PATCH 03/58] Feature - credentialsResolver setting added. #4713 --- .../client/DefaultCredentialsResolver.java | 39 +++++++ .../redisson/client/RedisClientConfig.java | 28 +++-- .../client/handler/BaseConnectionHandler.java | 100 +++++++++--------- .../java/org/redisson/config/BaseConfig.java | 20 ++++ .../org/redisson/config/ConfigSupport.java | 1 + .../java/org/redisson/config/Credentials.java | 48 +++++++++ .../redisson/config/CredentialsResolver.java | 39 +++++++ .../MasterSlaveConnectionManager.java | 6 +- .../connection/SingleConnectionManager.java | 1 + .../test/java/org/redisson/RedissonTest.java | 31 +++++- 10 files changed, 248 insertions(+), 65 deletions(-) create mode 100644 redisson/src/main/java/org/redisson/client/DefaultCredentialsResolver.java create mode 100644 redisson/src/main/java/org/redisson/config/Credentials.java create mode 100644 redisson/src/main/java/org/redisson/config/CredentialsResolver.java diff --git a/redisson/src/main/java/org/redisson/client/DefaultCredentialsResolver.java b/redisson/src/main/java/org/redisson/client/DefaultCredentialsResolver.java new file mode 100644 index 000000000..c671924e3 --- /dev/null +++ b/redisson/src/main/java/org/redisson/client/DefaultCredentialsResolver.java @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2013-2022 Nikita Koksharov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.redisson.client; + +import org.redisson.config.Credentials; +import org.redisson.config.CredentialsResolver; + +import java.net.InetSocketAddress; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; + +/** + * + * @author Nikita Koksharov + * + */ +public class DefaultCredentialsResolver implements CredentialsResolver { + + private final CompletionStage future = CompletableFuture.completedFuture(new Credentials()); + + @Override + public CompletionStage resolve(InetSocketAddress address) { + return future; + } + +} diff --git a/redisson/src/main/java/org/redisson/client/RedisClientConfig.java b/redisson/src/main/java/org/redisson/client/RedisClientConfig.java index d6512205f..be9f501e1 100644 --- a/redisson/src/main/java/org/redisson/client/RedisClientConfig.java +++ b/redisson/src/main/java/org/redisson/client/RedisClientConfig.java @@ -15,18 +15,18 @@ */ package org.redisson.client; -import java.net.InetSocketAddress; -import java.net.URL; -import java.util.concurrent.ExecutorService; - -import org.redisson.config.SslProvider; -import org.redisson.misc.RedisURI; - import io.netty.channel.EventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.resolver.AddressResolverGroup; import io.netty.util.Timer; +import org.redisson.config.CredentialsResolver; +import org.redisson.config.SslProvider; +import org.redisson.misc.RedisURI; + +import java.net.InetSocketAddress; +import java.net.URL; +import java.util.concurrent.ExecutorService; /** * @@ -65,6 +65,7 @@ public class RedisClientConfig { private String sslKeystorePassword; private String[] sslProtocols; private NettyHook nettyHook = new DefaultNettyHook(); + private CredentialsResolver credentialsResolver = new DefaultCredentialsResolver(); public RedisClientConfig() { } @@ -97,13 +98,15 @@ public class RedisClientConfig { this.sslKeystorePassword = config.sslKeystorePassword; this.resolverGroup = config.resolverGroup; this.sslHostname = config.sslHostname; + this.credentialsResolver = config.credentialsResolver; } public NettyHook getNettyHook() { return nettyHook; } - public void setNettyHook(NettyHook nettyHook) { + public RedisClientConfig setNettyHook(NettyHook nettyHook) { this.nettyHook = nettyHook; + return this; } public String getSslHostname() { @@ -321,4 +324,13 @@ public class RedisClientConfig { this.sslProtocols = sslProtocols; return this; } + + public CredentialsResolver getCredentialsResolver() { + return credentialsResolver; + } + + public RedisClientConfig setCredentialsResolver(CredentialsResolver credentialsResolver) { + this.credentialsResolver = credentialsResolver; + return this; + } } diff --git a/redisson/src/main/java/org/redisson/client/handler/BaseConnectionHandler.java b/redisson/src/main/java/org/redisson/client/handler/BaseConnectionHandler.java index 88d473618..c6b99c03b 100644 --- a/redisson/src/main/java/org/redisson/client/handler/BaseConnectionHandler.java +++ b/redisson/src/main/java/org/redisson/client/handler/BaseConnectionHandler.java @@ -17,20 +17,19 @@ package org.redisson.client.handler; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; -import org.redisson.api.RFuture; import org.redisson.client.RedisClient; import org.redisson.client.RedisClientConfig; import org.redisson.client.RedisConnection; import org.redisson.client.RedisLoadingException; import org.redisson.client.protocol.RedisCommands; +import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; /** * @@ -40,7 +39,7 @@ import java.util.concurrent.atomic.AtomicInteger; public abstract class BaseConnectionHandler extends ChannelInboundHandlerAdapter { final RedisClient redisClient; - final CompletableFuture connectionPromise = new CompletableFuture(); + final CompletableFuture connectionPromise = new CompletableFuture<>(); C connection; public BaseConnectionHandler(RedisClient redisClient) { @@ -60,66 +59,63 @@ public abstract class BaseConnectionHandler extends C @Override public void channelActive(ChannelHandlerContext ctx) { - List> futures = new ArrayList<>(); + List> futures = new ArrayList<>(5); + InetSocketAddress addr = redisClient.resolveAddr().getNow(null); RedisClientConfig config = redisClient.getConfig(); - String password = Objects.toString(config.getAddress().getPassword(), config.getPassword()); - if (password != null) { - RFuture future; - String username = Objects.toString(config.getAddress().getUsername(), config.getUsername()); - if (username != null) { - future = connection.async(RedisCommands.AUTH, username, password); - } else { - future = connection.async(RedisCommands.AUTH, password); - } - futures.add(future); - } + CompletionStage f = config.getCredentialsResolver().resolve(addr) + .thenCompose(credentials -> { + String password = Objects.toString(config.getAddress().getPassword(), + Objects.toString(credentials.getPassword(), config.getPassword())); + if (password != null) { + CompletionStage future; + String username = Objects.toString(config.getAddress().getUsername(), + Objects.toString(credentials.getUsername(), config.getUsername())); + if (username != null) { + future = connection.async(RedisCommands.AUTH, username, password); + } else { + future = connection.async(RedisCommands.AUTH, password); + } + return future; + } + return CompletableFuture.completedFuture(null); + }); + futures.add(f.toCompletableFuture()); + if (config.getDatabase() != 0) { - RFuture future = connection.async(RedisCommands.SELECT, config.getDatabase()); - futures.add(future); + CompletionStage future = connection.async(RedisCommands.SELECT, config.getDatabase()); + futures.add(future.toCompletableFuture()); } if (config.getClientName() != null) { - RFuture future = connection.async(RedisCommands.CLIENT_SETNAME, config.getClientName()); - futures.add(future); + CompletionStage future = connection.async(RedisCommands.CLIENT_SETNAME, config.getClientName()); + futures.add(future.toCompletableFuture()); } if (config.isReadOnly()) { - RFuture future = connection.async(RedisCommands.READONLY); - futures.add(future); + CompletionStage future = connection.async(RedisCommands.READONLY); + futures.add(future.toCompletableFuture()); } if (config.getPingConnectionInterval() > 0) { - RFuture future = connection.async(RedisCommands.PING); - futures.add(future); + CompletionStage future = connection.async(RedisCommands.PING); + futures.add(future.toCompletableFuture()); } - - if (futures.isEmpty()) { - ctx.fireChannelActive(); - connectionPromise.complete(connection); - return; - } - - AtomicBoolean retry = new AtomicBoolean(); - AtomicInteger commandsCounter = new AtomicInteger(futures.size()); - for (RFuture future : futures) { - future.whenComplete((res, e) -> { - if (e != null) { - if (e instanceof RedisLoadingException) { - if (retry.compareAndSet(false, true)) { - ctx.executor().schedule(() -> { - channelActive(ctx); - }, 1, TimeUnit.SECONDS); - } - return; - } - connection.closeAsync(); - connectionPromise.completeExceptionally(e); + + CompletableFuture future = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); + future.whenComplete((res, e) -> { + if (e != null) { + if (e instanceof RedisLoadingException) { + ctx.executor().schedule(() -> { + channelActive(ctx); + }, 1, TimeUnit.SECONDS); return; } - if (commandsCounter.decrementAndGet() == 0) { - ctx.fireChannelActive(); - connectionPromise.complete(connection); - } - }); - } + connection.closeAsync(); + connectionPromise.completeExceptionally(e); + return; + } + + ctx.fireChannelActive(); + connectionPromise.complete(connection); + }); } } diff --git a/redisson/src/main/java/org/redisson/config/BaseConfig.java b/redisson/src/main/java/org/redisson/config/BaseConfig.java index 79ee412ba..6bf8e4129 100644 --- a/redisson/src/main/java/org/redisson/config/BaseConfig.java +++ b/redisson/src/main/java/org/redisson/config/BaseConfig.java @@ -16,6 +16,7 @@ package org.redisson.config; import org.redisson.api.NameMapper; +import org.redisson.client.DefaultCredentialsResolver; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -65,6 +66,8 @@ public class BaseConfig> { private String username; + private CredentialsResolver credentialsResolver = new DefaultCredentialsResolver(); + /** * Subscriptions per Redis connection limit */ @@ -122,6 +125,7 @@ public class BaseConfig> { setKeepAlive(config.isKeepAlive()); setTcpNoDelay(config.isTcpNoDelay()); setNameMapper(config.getNameMapper()); + setCredentialsResolver(config.getCredentialsResolver()); } /** @@ -475,4 +479,20 @@ public class BaseConfig> { this.nameMapper = nameMapper; return (T) this; } + + public CredentialsResolver getCredentialsResolver() { + return credentialsResolver; + } + + /** + * Defines Credentials resolver which is invoked during connection/reconnection process. + * It makes possible to specify dynamically changing Redis credentials. + * + * @param credentialsResolver Credentials resolver object + * @return config + */ + public T setCredentialsResolver(CredentialsResolver credentialsResolver) { + this.credentialsResolver = credentialsResolver; + return (T) this; + } } diff --git a/redisson/src/main/java/org/redisson/config/ConfigSupport.java b/redisson/src/main/java/org/redisson/config/ConfigSupport.java index 4bd0f5bd0..35083373e 100644 --- a/redisson/src/main/java/org/redisson/config/ConfigSupport.java +++ b/redisson/src/main/java/org/redisson/config/ConfigSupport.java @@ -234,6 +234,7 @@ public class ConfigSupport { mapper.addMixIn(NatMapper.class, ClassMixIn.class); mapper.addMixIn(NameMapper.class, ClassMixIn.class); mapper.addMixIn(NettyHook.class, ClassMixIn.class); + mapper.addMixIn(CredentialsResolver.class, ClassMixIn.class); FilterProvider filterProvider = new SimpleFilterProvider() .addFilter("classFilter", SimpleBeanPropertyFilter.filterOutAllExcept()); diff --git a/redisson/src/main/java/org/redisson/config/Credentials.java b/redisson/src/main/java/org/redisson/config/Credentials.java new file mode 100644 index 000000000..1e013af45 --- /dev/null +++ b/redisson/src/main/java/org/redisson/config/Credentials.java @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2013-2022 Nikita Koksharov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.redisson.config; + +import java.io.Serializable; + +/** + * Credentials object with username and password used for Redis connection. + * + * @author Nikita Koksharov + * + */ +public class Credentials implements Serializable { + + private String username; + + private String password; + + public Credentials() { + } + + public Credentials(String username, String password) { + this.username = username; + this.password = password; + } + + public String getPassword() { + return password; + } + + public String getUsername() { + return username; + } + +} diff --git a/redisson/src/main/java/org/redisson/config/CredentialsResolver.java b/redisson/src/main/java/org/redisson/config/CredentialsResolver.java new file mode 100644 index 000000000..ab2562080 --- /dev/null +++ b/redisson/src/main/java/org/redisson/config/CredentialsResolver.java @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2013-2022 Nikita Koksharov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.redisson.config; + +import java.net.InetSocketAddress; +import java.util.concurrent.CompletionStage; + +/** + * Credentials resolver object which is invoked during connection/reconnection process. + * It makes possible to specify dynamically changing Redis credentials. + * + * @author Nikita Koksharov + * + */ +public interface CredentialsResolver { + + /** + * Asynchronously resolves Credentials object + * for specified Redis node address . + * + * @param address address of Redis node + * @return Credentials object + */ + CompletionStage resolve(InetSocketAddress address); + +} diff --git a/redisson/src/main/java/org/redisson/connection/MasterSlaveConnectionManager.java b/redisson/src/main/java/org/redisson/connection/MasterSlaveConnectionManager.java index 1fdc4b5bf..016cd0d1f 100644 --- a/redisson/src/main/java/org/redisson/connection/MasterSlaveConnectionManager.java +++ b/redisson/src/main/java/org/redisson/connection/MasterSlaveConnectionManager.java @@ -402,6 +402,7 @@ public class MasterSlaveConnectionManager implements ConnectionManager { c.setKeepAlive(cfg.isKeepAlive()); c.setTcpNoDelay(cfg.isTcpNoDelay()); c.setNameMapper(cfg.getNameMapper()); + c.setCredentialsResolver(cfg.getCredentialsResolver()); return c; } @@ -456,8 +457,9 @@ public class MasterSlaveConnectionManager implements ConnectionManager { .setTcpNoDelay(config.isTcpNoDelay()) .setUsername(config.getUsername()) .setPassword(config.getPassword()) - .setNettyHook(cfg.getNettyHook()); - + .setNettyHook(cfg.getNettyHook()) + .setCredentialsResolver(config.getCredentialsResolver()); + if (type != NodeType.SENTINEL) { redisConfig.setDatabase(config.getDatabase()); } diff --git a/redisson/src/main/java/org/redisson/connection/SingleConnectionManager.java b/redisson/src/main/java/org/redisson/connection/SingleConnectionManager.java index 911d20b15..1b97ebf10 100644 --- a/redisson/src/main/java/org/redisson/connection/SingleConnectionManager.java +++ b/redisson/src/main/java/org/redisson/connection/SingleConnectionManager.java @@ -64,6 +64,7 @@ public class SingleConnectionManager extends MasterSlaveConnectionManager { newconfig.setKeepAlive(cfg.isKeepAlive()); newconfig.setTcpNoDelay(cfg.isTcpNoDelay()); newconfig.setNameMapper(cfg.getNameMapper()); + newconfig.setCredentialsResolver(cfg.getCredentialsResolver()); return newconfig; } diff --git a/redisson/src/test/java/org/redisson/RedissonTest.java b/redisson/src/test/java/org/redisson/RedissonTest.java index 2d5dafefe..407d582f0 100644 --- a/redisson/src/test/java/org/redisson/RedissonTest.java +++ b/redisson/src/test/java/org/redisson/RedissonTest.java @@ -23,9 +23,7 @@ import org.redisson.cluster.ClusterNodeInfo; import org.redisson.cluster.ClusterNodeInfo.Flag; import org.redisson.codec.JsonJacksonCodec; import org.redisson.codec.SerializationCodec; -import org.redisson.config.Config; -import org.redisson.config.ReadMode; -import org.redisson.config.SubscriptionMode; +import org.redisson.config.*; import org.redisson.connection.CRC16; import org.redisson.connection.ConnectionListener; import org.redisson.connection.MasterSlaveConnectionManager; @@ -851,6 +849,33 @@ public class RedissonTest extends BaseTest { Assertions.assertTrue(r.isShutdown()); } + @Test + public void testCredentials() throws IOException, InterruptedException { + RedisProcess runner = new RedisRunner() + .nosave() + .randomDir() + .randomPort() + .requirepass("1234") + .run(); + + Config config = new Config(); + config.useSingleServer() + .setCredentialsResolver(new CredentialsResolver() { + @Override + public CompletionStage resolve(InetSocketAddress address) { + return CompletableFuture.completedFuture(new Credentials(null, "1234")); + } + }) + .setAddress(runner.getRedisServerAddressAndPort()); + RedissonClient redisson = Redisson.create(config); + RBucket b = redisson.getBucket("test"); + b.set("123"); + + redisson.shutdown(); + runner.stop(); + + } + @Test public void testURIPassword() throws InterruptedException, IOException { RedisProcess runner = new RedisRunner() From 60532e10e1ee8098afd626ca19a0292c378226e4 Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Tue, 6 Dec 2022 08:39:22 +0300 Subject: [PATCH 04/58] javadoc fixed --- redisson/src/main/java/org/redisson/config/BaseConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redisson/src/main/java/org/redisson/config/BaseConfig.java b/redisson/src/main/java/org/redisson/config/BaseConfig.java index 6bf8e4129..1768d8b42 100644 --- a/redisson/src/main/java/org/redisson/config/BaseConfig.java +++ b/redisson/src/main/java/org/redisson/config/BaseConfig.java @@ -485,7 +485,7 @@ public class BaseConfig> { } /** - * Defines Credentials resolver which is invoked during connection/reconnection process. + * Defines Credentials resolver which is invoked during connection for Redis server authentication. * It makes possible to specify dynamically changing Redis credentials. * * @param credentialsResolver Credentials resolver object From aa08f8b99b4057be68f438923d228911586f4162 Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Tue, 6 Dec 2022 08:56:08 +0300 Subject: [PATCH 05/58] refactoring --- redisson/src/main/java/org/redisson/RedisNodes.java | 4 ++-- .../org/redisson/cluster/ClusterConnectionManager.java | 2 +- .../connection/MasterSlaveConnectionManager.java | 4 ++-- .../java/org/redisson/connection/MasterSlaveEntry.java | 4 ++-- .../connection/ReplicatedConnectionManager.java | 2 +- .../connection/balancer/LoadBalancerManager.java | 2 +- redisson/src/main/java/org/redisson/misc/RedisURI.java | 10 +++++----- .../java/org/redisson/redisnode/RedissonBaseNodes.java | 4 ++-- .../redisnode/RedissonSentinelMasterSlaveNodes.java | 2 +- 9 files changed, 17 insertions(+), 17 deletions(-) diff --git a/redisson/src/main/java/org/redisson/RedisNodes.java b/redisson/src/main/java/org/redisson/RedisNodes.java index acacb9e3d..04c4a6f3b 100644 --- a/redisson/src/main/java/org/redisson/RedisNodes.java +++ b/redisson/src/main/java/org/redisson/RedisNodes.java @@ -56,12 +56,12 @@ public class RedisNodes implements NodesGroup { RedisURI addr = new RedisURI(address); for (MasterSlaveEntry masterSlaveEntry : entries) { if (masterSlaveEntry.getAllEntries().isEmpty() - && RedisURI.compare(masterSlaveEntry.getClient().getAddr(), addr)) { + && addr.equals(masterSlaveEntry.getClient().getAddr())) { return (N) new RedisClientEntry(masterSlaveEntry.getClient(), commandExecutor, NodeType.MASTER); } for (ClientConnectionsEntry entry : masterSlaveEntry.getAllEntries()) { - if (RedisURI.compare(entry.getClient().getAddr(), addr) + if (addr.equals(entry.getClient().getAddr()) && entry.getFreezeReason() != FreezeReason.MANAGER) { return (N) new RedisClientEntry(entry.getClient(), commandExecutor, entry.getNodeType()); } diff --git a/redisson/src/main/java/org/redisson/cluster/ClusterConnectionManager.java b/redisson/src/main/java/org/redisson/cluster/ClusterConnectionManager.java index 73199cf60..18212b7ab 100644 --- a/redisson/src/main/java/org/redisson/cluster/ClusterConnectionManager.java +++ b/redisson/src/main/java/org/redisson/cluster/ClusterConnectionManager.java @@ -174,7 +174,7 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager { protected MasterSlaveEntry getEntry(RedisURI addr) { for (MasterSlaveEntry entry : client2entry.values()) { - if (RedisURI.compare(entry.getClient().getAddr(), addr)) { + if (addr.equals(entry.getClient().getAddr())) { return entry; } if (entry.hasSlave(addr)) { diff --git a/redisson/src/main/java/org/redisson/connection/MasterSlaveConnectionManager.java b/redisson/src/main/java/org/redisson/connection/MasterSlaveConnectionManager.java index 016cd0d1f..903d86caa 100644 --- a/redisson/src/main/java/org/redisson/connection/MasterSlaveConnectionManager.java +++ b/redisson/src/main/java/org/redisson/connection/MasterSlaveConnectionManager.java @@ -516,8 +516,8 @@ public class MasterSlaveConnectionManager implements ConnectionManager { return f; } // fix for https://github.com/redisson/redisson/issues/1548 - if (source.getRedirect() != null - && !RedisURI.compare(entry.getClient().getAddr(), source.getAddr()) + if (source.getRedirect() != null + && !source.getAddr().equals(entry.getClient().getAddr()) && entry.hasSlave(source.getAddr())) { return entry.redirectedConnectionWriteOp(command, source.getAddr()); } diff --git a/redisson/src/main/java/org/redisson/connection/MasterSlaveEntry.java b/redisson/src/main/java/org/redisson/connection/MasterSlaveEntry.java index cb3bbc608..f1fb125ab 100644 --- a/redisson/src/main/java/org/redisson/connection/MasterSlaveEntry.java +++ b/redisson/src/main/java/org/redisson/connection/MasterSlaveEntry.java @@ -427,7 +427,7 @@ public class MasterSlaveEntry { InetSocketAddress addr = masterEntry.getClient().getAddr(); // exclude master from slaves if (!config.checkSkipSlavesInit() - && !RedisURI.compare(addr, address)) { + && !address.equals(addr)) { if (slaveDown(addr, FreezeReason.SYSTEM)) { log.info("master {} excluded from slaves", addr); } @@ -437,7 +437,7 @@ public class MasterSlaveEntry { public CompletableFuture excludeMasterFromSlaves(RedisURI address) { InetSocketAddress addr = masterEntry.getClient().getAddr(); - if (RedisURI.compare(addr, address)) { + if (address.equals(addr)) { return CompletableFuture.completedFuture(false); } CompletableFuture downFuture = slaveDownAsync(addr, FreezeReason.SYSTEM); diff --git a/redisson/src/main/java/org/redisson/connection/ReplicatedConnectionManager.java b/redisson/src/main/java/org/redisson/connection/ReplicatedConnectionManager.java index 7fc5c4215..501fa1f4a 100644 --- a/redisson/src/main/java/org/redisson/connection/ReplicatedConnectionManager.java +++ b/redisson/src/main/java/org/redisson/connection/ReplicatedConnectionManager.java @@ -170,7 +170,7 @@ public class ReplicatedConnectionManager extends MasterSlaveConnectionManager { } RedisConnection connection = connectionFuture.toCompletableFuture().join(); - if (!RedisURI.compare(connection.getRedisClient().getAddr(), ip)) { + if (!ip.equals(connection.getRedisClient().getAddr())) { disconnectNode(uri); log.info("Hostname: " + uri + " has changed IP from: " + connection.getRedisClient().getAddr() + " to " + ip); diff --git a/redisson/src/main/java/org/redisson/connection/balancer/LoadBalancerManager.java b/redisson/src/main/java/org/redisson/connection/balancer/LoadBalancerManager.java index b94d35d39..ee0d6acfb 100644 --- a/redisson/src/main/java/org/redisson/connection/balancer/LoadBalancerManager.java +++ b/redisson/src/main/java/org/redisson/connection/balancer/LoadBalancerManager.java @@ -268,7 +268,7 @@ public class LoadBalancerManager { public ClientConnectionsEntry getEntry(RedisURI addr) { for (ClientConnectionsEntry entry : client2Entry.values()) { InetSocketAddress entryAddr = entry.getClient().getAddr(); - if (RedisURI.compare(entryAddr, addr)) { + if (addr.equals(entryAddr)) { return entry; } } diff --git a/redisson/src/main/java/org/redisson/misc/RedisURI.java b/redisson/src/main/java/org/redisson/misc/RedisURI.java index 7dc632d97..b60aef8b3 100644 --- a/redisson/src/main/java/org/redisson/misc/RedisURI.java +++ b/redisson/src/main/java/org/redisson/misc/RedisURI.java @@ -111,17 +111,17 @@ public class RedisURI { return NetUtil.createByteArrayFromIpAddressString(host) != null; } - private static String trimIpv6Brackets(String host) { + private String trimIpv6Brackets(String host) { if (host.startsWith("[") && host.endsWith("]")) { return host.substring(1, host.length() - 1); } return host; } - public static boolean compare(InetSocketAddress entryAddr, RedisURI addr) { - if (((entryAddr.getHostName() != null && entryAddr.getHostName().equals(trimIpv6Brackets(addr.getHost()))) - || entryAddr.getAddress().getHostAddress().equals(trimIpv6Brackets(addr.getHost()))) - && entryAddr.getPort() == addr.getPort()) { + public boolean equals(InetSocketAddress entryAddr) { + if (((entryAddr.getHostName() != null && entryAddr.getHostName().equals(trimIpv6Brackets(getHost()))) + || entryAddr.getAddress().getHostAddress().equals(trimIpv6Brackets(getHost()))) + && entryAddr.getPort() == getPort()) { return true; } return false; diff --git a/redisson/src/main/java/org/redisson/redisnode/RedissonBaseNodes.java b/redisson/src/main/java/org/redisson/redisnode/RedissonBaseNodes.java index 379fc01f9..d39dde682 100644 --- a/redisson/src/main/java/org/redisson/redisnode/RedissonBaseNodes.java +++ b/redisson/src/main/java/org/redisson/redisnode/RedissonBaseNodes.java @@ -75,12 +75,12 @@ public class RedissonBaseNodes implements BaseRedisNodes { for (MasterSlaveEntry masterSlaveEntry : entries) { if (nodeType == NodeType.MASTER && masterSlaveEntry.getAllEntries().isEmpty() - && RedisURI.compare(masterSlaveEntry.getClient().getAddr(), addr)) { + && addr.equals(masterSlaveEntry.getClient().getAddr())) { return new RedisNode(masterSlaveEntry.getClient(), commandExecutor, NodeType.MASTER); } for (ClientConnectionsEntry entry : masterSlaveEntry.getAllEntries()) { - if (RedisURI.compare(entry.getClient().getAddr(), addr) + if (addr.equals(entry.getClient().getAddr()) && entry.getFreezeReason() != ClientConnectionsEntry.FreezeReason.MANAGER) { return new RedisNode(entry.getClient(), commandExecutor, entry.getNodeType()); } diff --git a/redisson/src/main/java/org/redisson/redisnode/RedissonSentinelMasterSlaveNodes.java b/redisson/src/main/java/org/redisson/redisnode/RedissonSentinelMasterSlaveNodes.java index ecbf4bfd7..efccadecc 100644 --- a/redisson/src/main/java/org/redisson/redisnode/RedissonSentinelMasterSlaveNodes.java +++ b/redisson/src/main/java/org/redisson/redisnode/RedissonSentinelMasterSlaveNodes.java @@ -47,7 +47,7 @@ public class RedissonSentinelMasterSlaveNodes extends RedissonMasterSlaveNodes i public RedisSentinel getSentinel(String address) { RedisURI addr = new RedisURI(address); return ((SentinelConnectionManager) connectionManager).getSentinels().stream() - .filter(c -> RedisURI.compare(c.getAddr(), addr)) + .filter(c -> addr.equals(c.getAddr())) .map(c -> new SentinelRedisNode(c, commandExecutor)) .findFirst().orElse(null); } From cd0401b9c12ea9f029090a23d264f0eaf6ff874e Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Tue, 6 Dec 2022 09:04:26 +0300 Subject: [PATCH 06/58] Feature - added FencedLock implementation. #4684 --- .../java/org/redisson/RedissonFencedLock.java | 49 ++++++++++++++++--- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/redisson/src/main/java/org/redisson/RedissonFencedLock.java b/redisson/src/main/java/org/redisson/RedissonFencedLock.java index f5a4d88aa..a9d2ae043 100644 --- a/redisson/src/main/java/org/redisson/RedissonFencedLock.java +++ b/redisson/src/main/java/org/redisson/RedissonFencedLock.java @@ -35,14 +35,23 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; +/** + * Redis based implementation of Fenced Lock with reentrancy support. + *

+ * Each lock acquisition increases fencing token. It should be + * checked if it's greater or equal with the previous one by + * the service guarded by this lock and reject operation if condition is false. + * + * @author Nikita Koksharov + * + */ public class RedissonFencedLock extends RedissonLock implements RFencedLock { + private final String tokenName; + public RedissonFencedLock(CommandAsyncExecutor commandExecutor, String name) { super(commandExecutor, name); - } - - String getTokenName() { - return prefixName("redisson_lock_token", getRawName()); + tokenName = prefixName("redisson_lock_token", getRawName()); } @Override @@ -52,7 +61,7 @@ public class RedissonFencedLock extends RedissonLock implements RFencedLock { @Override public RFuture getTokenAsync() { - return commandExecutor.writeAsync(getTokenName(), StringCodec.INSTANCE, RedisCommands.GET_LONG, getTokenName()); + return commandExecutor.writeAsync(tokenName, StringCodec.INSTANCE, RedisCommands.GET_LONG, tokenName); } @Override @@ -105,7 +114,7 @@ public class RedissonFencedLock extends RedissonLock implements RFencedLock { "return {-1, token}; " + "end; " + "return {redis.call('pttl', KEYS[1]), -1};", - Arrays.asList(getRawName(), getTokenName()), + Arrays.asList(getRawName(), tokenName), unit.toMillis(leaseTime), getLockName(threadId)); } @@ -298,8 +307,34 @@ public class RedissonFencedLock extends RedissonLock implements RFencedLock { "return nil; " + "end; " + "return redis.call('pttl', KEYS[1]);", - Arrays.asList(getRawName(), getTokenName()), + Arrays.asList(getRawName(), tokenName), unit.toMillis(leaseTime), getLockName(threadId)); } + @Override + public RFuture deleteAsync() { + return deleteAsync(getRawName(), tokenName); + } + + @Override + public RFuture sizeInMemoryAsync() { + List keys = Arrays.asList(getRawName(), tokenName); + return super.sizeInMemoryAsync(keys); + } + + @Override + public RFuture expireAsync(long timeToLive, TimeUnit timeUnit, String param, String... keys) { + return super.expireAsync(timeToLive, timeUnit, param, getRawName(), tokenName); + } + + @Override + protected RFuture expireAtAsync(long timestamp, String param, String... keys) { + return super.expireAtAsync(timestamp, param, getRawName(), tokenName); + } + + @Override + public RFuture clearExpireAsync() { + return clearExpireAsync(getRawName(), tokenName); + } + } From b96dad37b1fec169bd01d321509ed096e772dd6a Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Tue, 6 Dec 2022 14:45:16 +0300 Subject: [PATCH 07/58] Improvement - Use Kryo 5 codec by default #4722 --- .../redisson-hibernate-4/pom.xml | 16 ++++++++++ .../redisson-hibernate-5/pom.xml | 16 ++++++++++ .../redisson-hibernate-52/pom.xml | 15 ++++++++++ .../redisson-hibernate-53/pom.xml | 15 ++++++++++ .../redisson-hibernate-6/pom.xml | 21 +++++++++++-- redisson-micronaut/README.md | 18 +++++------ .../cache/BaseCacheConfiguration.java | 4 +-- .../RedissonHttpSessionConfiguration.java | 4 +-- .../cache/BaseCacheConfiguration.java | 4 +-- .../RedissonHttpSessionConfiguration.java | 4 +-- .../QuarkusRedissonClientProcessor.java | 3 +- .../src/main/resources/application.properties | 2 +- .../QuarkusRedissonClientProcessor.java | 3 +- .../src/main/resources/application.properties | 2 +- redisson-spring-boot-starter/README.md | 2 +- redisson/pom.xml | 12 ++++++-- .../java/org/redisson/codec/Kryo5Codec.java | 2 ++ .../java/org/redisson/codec/LZ4Codec.java | 23 +++++++------- .../java/org/redisson/codec/SnappyCodec.java | 4 +-- .../org/redisson/codec/SnappyCodecV2.java | 8 ++--- .../main/java/org/redisson/config/Config.java | 8 ++--- .../java/org/redisson/RedissonBucketTest.java | 4 +-- .../java/org/redisson/RedissonQueueTest.java | 30 +++++++++++++++++++ 23 files changed, 168 insertions(+), 52 deletions(-) diff --git a/redisson-hibernate/redisson-hibernate-4/pom.xml b/redisson-hibernate/redisson-hibernate-4/pom.xml index 170580ab8..36b5ce403 100644 --- a/redisson-hibernate/redisson-hibernate-4/pom.xml +++ b/redisson-hibernate/redisson-hibernate-4/pom.xml @@ -37,6 +37,22 @@ + + + org.apache.maven.plugins + maven-surefire-plugin + + true + 2 + true + + --add-opens=java.base/java.lang.reflect=ALL-UNNAMED + --add-opens=java.base/java.util=ALL-UNNAMED + -javaagent:"${settings.localRepository}"/org/jmockit/jmockit/1.49/jmockit-1.49.jar + + + + maven-jar-plugin 3.1.2 diff --git a/redisson-hibernate/redisson-hibernate-5/pom.xml b/redisson-hibernate/redisson-hibernate-5/pom.xml index 636d875a9..817fc9241 100644 --- a/redisson-hibernate/redisson-hibernate-5/pom.xml +++ b/redisson-hibernate/redisson-hibernate-5/pom.xml @@ -57,6 +57,22 @@ + + + org.apache.maven.plugins + maven-surefire-plugin + + true + 2 + true + + --add-opens=java.base/java.lang.reflect=ALL-UNNAMED + --add-opens=java.base/java.util=ALL-UNNAMED + -javaagent:"${settings.localRepository}"/org/jmockit/jmockit/1.49/jmockit-1.49.jar + + + + maven-jar-plugin 3.1.2 diff --git a/redisson-hibernate/redisson-hibernate-52/pom.xml b/redisson-hibernate/redisson-hibernate-52/pom.xml index ea300e467..f78eb8bc3 100644 --- a/redisson-hibernate/redisson-hibernate-52/pom.xml +++ b/redisson-hibernate/redisson-hibernate-52/pom.xml @@ -50,6 +50,21 @@ + + org.apache.maven.plugins + maven-surefire-plugin + + true + 2 + true + + --add-opens=java.base/java.lang.reflect=ALL-UNNAMED + --add-opens=java.base/java.util=ALL-UNNAMED + -javaagent:"${settings.localRepository}"/org/jmockit/jmockit/1.49/jmockit-1.49.jar + + + + maven-jar-plugin 3.1.2 diff --git a/redisson-hibernate/redisson-hibernate-53/pom.xml b/redisson-hibernate/redisson-hibernate-53/pom.xml index 20920ce98..9c6873708 100644 --- a/redisson-hibernate/redisson-hibernate-53/pom.xml +++ b/redisson-hibernate/redisson-hibernate-53/pom.xml @@ -44,6 +44,21 @@ + + org.apache.maven.plugins + maven-surefire-plugin + + true + 2 + true + + --add-opens=java.base/java.lang.reflect=ALL-UNNAMED + --add-opens=java.base/java.util=ALL-UNNAMED + -javaagent:"${settings.localRepository}"/org/jmockit/jmockit/1.49/jmockit-1.49.jar + + + + maven-jar-plugin 3.1.2 diff --git a/redisson-hibernate/redisson-hibernate-6/pom.xml b/redisson-hibernate/redisson-hibernate-6/pom.xml index df3d8b35d..6ce4cc60d 100644 --- a/redisson-hibernate/redisson-hibernate-6/pom.xml +++ b/redisson-hibernate/redisson-hibernate-6/pom.xml @@ -28,23 +28,40 @@ test + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + 2 + true + + --add-opens=java.base/java.util=ALL-UNNAMED + -javaagent:"${settings.localRepository}"/org/jmockit/jmockit/1.49/jmockit-1.49.jar + + + + maven-jar-plugin 3.1.2 diff --git a/redisson-micronaut/README.md b/redisson-micronaut/README.md index 3983add5b..521ebd3e6 100644 --- a/redisson-micronaut/README.md +++ b/redisson-micronaut/README.md @@ -81,7 +81,7 @@ redisson: |Setting name| `redisson.caches.[CACHE_NAME].codec` | |Type| `java.lang.Class` | |Description| Redis data codec applied to cache entries. | -|Default value| `MarshallingCodec` | +|Default value| `Kryo5Codec` | | | | |-|-| @@ -143,7 +143,7 @@ redisson: expire-after-write: 10s expire-after-access: 3s max-size: 1000 - codec: org.redisson.codec.MarshallingCodec + codec: org.redisson.codec.Kryo5Codec my-cache2: expire-after-write: 200s expire-after-access: 30s @@ -169,7 +169,7 @@ _This feature is available only in [Redisson PRO](https://redisson.pro)_ |Setting name| `redisson.clustered-caches.[CACHE_NAME].codec` | |Type| `java.lang.Class` | |Description| Redis data codec applied to cache entries. | -|Default value| `MarshallingCodec` | +|Default value| `Kryo5Codec` | | | | |-|-| @@ -230,7 +230,7 @@ redisson: expire-after-write: 10s expire-after-access: 3s max-size: 1000 - codec: org.redisson.codec.MarshallingCodec + codec: org.redisson.codec.Kryo5Codec my-cache2: expire-after-write: 200s expire-after-access: 30s @@ -256,7 +256,7 @@ _This feature is available only in [Redisson PRO](https://redisson.pro)_ |Setting name| `redisson.clustered-local-caches.[CACHE_NAME].codec` | |Type| `java.lang.Class` | |Description| Redis data codec applied to cache entries. | -|Default value| `MarshallingCodec` | +|Default value| `Kryo5Codec` | | | | |-|-| @@ -375,7 +375,7 @@ redisson: expire-after-write: 10s expire-after-access: 3s max-size: 1000 - codec: org.redisson.codec.MarshallingCodec + codec: org.redisson.codec.Kryo5Codec store-сache-miss: true eviction-policy: `WEAK` cache-size: 5000 @@ -404,7 +404,7 @@ _This feature is available only in [Redisson PRO](https://redisson.pro)_ |Setting name| `redisson.local-caches.[CACHE_NAME].codec` | |Type| `java.lang.Class` | |Description| Redis data codec applied to cache entries. | -|Default value| `MarshallingCodec` | +|Default value| `Kryo5Codec` | | | | |-|-| @@ -523,7 +523,7 @@ redisson: expire-after-write: 10s expire-after-access: 3s max-size: 1000 - codec: org.redisson.codec.MarshallingCodec + codec: org.redisson.codec.Kryo5Codec store-сache-miss: true eviction-policy: `WEAK` cache-size: 5000 @@ -542,7 +542,7 @@ Additional settings to [HttpSessionConfiguration](https://docs.micronaut.io/2.5. |------------|----|-----------| |micronaut.session.http.redisson.enabled|java.lang.Boolean|Enables Session store| |micronaut.session.http.redisson.key-prefix|java.lang.Integer|Defines string prefix applied to all objects stored in Redis.| -|micronaut.session.http.redisson.codec|java.lang.Class|Redis data codec applied to cache entries. Default is MarshallingCodec codec.| +|micronaut.session.http.redisson.codec|java.lang.Class|Redis data codec applied to cache entries. Default is Kryo5Codec codec.| |micronaut.session.http.redisson.update-mode|java.lang.String|Defines session attributes update mode.
`WRITE_BEHIND` - session changes stored asynchronously.
`AFTER_REQUEST` - session changes stored only on `SessionStore#save(Session)` method invocation. Default value.| |micronaut.session.http.redisson.broadcastSessionUpdates|java.lang.Boolean|Defines broadcasting of session updates across all micronaut services.| diff --git a/redisson-micronaut/redisson-micronaut-20/src/main/java/org/redisson/micronaut/cache/BaseCacheConfiguration.java b/redisson-micronaut/redisson-micronaut-20/src/main/java/org/redisson/micronaut/cache/BaseCacheConfiguration.java index 76d215b62..5cb3a2abd 100644 --- a/redisson-micronaut/redisson-micronaut-20/src/main/java/org/redisson/micronaut/cache/BaseCacheConfiguration.java +++ b/redisson-micronaut/redisson-micronaut-20/src/main/java/org/redisson/micronaut/cache/BaseCacheConfiguration.java @@ -57,10 +57,10 @@ public class BaseCacheConfiguration implements Named { /** * Redis data codec applied to cache entries. - * Default is MarshallingCodec codec + * Default is Kryo5Codec codec * * @see Codec - * @see org.redisson.codec.MarshallingCodec + * @see org.redisson.codec.Kryo5Codec * * @param codec - data codec * @return config diff --git a/redisson-micronaut/redisson-micronaut-20/src/main/java/org/redisson/micronaut/session/RedissonHttpSessionConfiguration.java b/redisson-micronaut/redisson-micronaut-20/src/main/java/org/redisson/micronaut/session/RedissonHttpSessionConfiguration.java index a255ea0d0..fe7c9f4ca 100644 --- a/redisson-micronaut/redisson-micronaut-20/src/main/java/org/redisson/micronaut/session/RedissonHttpSessionConfiguration.java +++ b/redisson-micronaut/redisson-micronaut-20/src/main/java/org/redisson/micronaut/session/RedissonHttpSessionConfiguration.java @@ -72,10 +72,10 @@ public class RedissonHttpSessionConfiguration extends HttpSessionConfiguration i /** * Redis data codec applied to session values. - * Default is MarshallingCodec codec + * Default is Kryo5Codec codec * * @see org.redisson.client.codec.Codec - * @see org.redisson.codec.MarshallingCodec + * @see org.redisson.codec.Kryo5Codec * * @param codec - data codec * @return config diff --git a/redisson-micronaut/redisson-micronaut-30/src/main/java/org/redisson/micronaut/cache/BaseCacheConfiguration.java b/redisson-micronaut/redisson-micronaut-30/src/main/java/org/redisson/micronaut/cache/BaseCacheConfiguration.java index 7f4f75571..f29ce45e8 100644 --- a/redisson-micronaut/redisson-micronaut-30/src/main/java/org/redisson/micronaut/cache/BaseCacheConfiguration.java +++ b/redisson-micronaut/redisson-micronaut-30/src/main/java/org/redisson/micronaut/cache/BaseCacheConfiguration.java @@ -57,10 +57,10 @@ public class BaseCacheConfiguration implements Named { /** * Redis data codec applied to cache entries. - * Default is MarshallingCodec codec + * Default is Kryo5Codec codec * * @see Codec - * @see org.redisson.codec.MarshallingCodec + * @see org.redisson.codec.Kryo5Codec * * @param codec - data codec * @return config diff --git a/redisson-micronaut/redisson-micronaut-30/src/main/java/org/redisson/micronaut/session/RedissonHttpSessionConfiguration.java b/redisson-micronaut/redisson-micronaut-30/src/main/java/org/redisson/micronaut/session/RedissonHttpSessionConfiguration.java index a255ea0d0..fe7c9f4ca 100644 --- a/redisson-micronaut/redisson-micronaut-30/src/main/java/org/redisson/micronaut/session/RedissonHttpSessionConfiguration.java +++ b/redisson-micronaut/redisson-micronaut-30/src/main/java/org/redisson/micronaut/session/RedissonHttpSessionConfiguration.java @@ -72,10 +72,10 @@ public class RedissonHttpSessionConfiguration extends HttpSessionConfiguration i /** * Redis data codec applied to session values. - * Default is MarshallingCodec codec + * Default is Kryo5Codec codec * * @see org.redisson.client.codec.Codec - * @see org.redisson.codec.MarshallingCodec + * @see org.redisson.codec.Kryo5Codec * * @param codec - data codec * @return config diff --git a/redisson-quarkus/redisson-quarkus-16/deployment/src/main/java/io/quarkus/redisson/client/deployment/QuarkusRedissonClientProcessor.java b/redisson-quarkus/redisson-quarkus-16/deployment/src/main/java/io/quarkus/redisson/client/deployment/QuarkusRedissonClientProcessor.java index b4a69f40a..ac966d61a 100644 --- a/redisson-quarkus/redisson-quarkus-16/deployment/src/main/java/io/quarkus/redisson/client/deployment/QuarkusRedissonClientProcessor.java +++ b/redisson-quarkus/redisson-quarkus-16/deployment/src/main/java/io/quarkus/redisson/client/deployment/QuarkusRedissonClientProcessor.java @@ -64,8 +64,7 @@ class QuarkusRedissonClientProcessor { nativeResources.produce(new NativeImageResourceBuildItem("META-INF/services/org.jboss.marshalling.ProviderDescriptor")); watchedFiles.produce(new HotDeploymentWatchedFileBuildItem("redisson.yaml")); - reflectiveItems.produce(new ReflectiveClassBuildItem(false, false, "org.redisson.codec.MarshallingCodec")); - reflectiveItems.produce(new ReflectiveClassBuildItem(false, false, "org.jboss.marshalling.river.RiverProviderDescriptor")); + reflectiveItems.produce(new ReflectiveClassBuildItem(false, false, "org.redisson.codec.Kryo5Codec")); reflectiveItems.produce(new ReflectiveClassBuildItem(true, false, "org.redisson.executor.RemoteExecutorService")); reflectiveItems.produce(new ReflectiveClassBuildItem(true, false, "org.redisson.executor.RemoteExecutorServiceAsync")); diff --git a/redisson-quarkus/redisson-quarkus-16/integration-tests/src/main/resources/application.properties b/redisson-quarkus/redisson-quarkus-16/integration-tests/src/main/resources/application.properties index 3d20bb524..af4e01f47 100644 --- a/redisson-quarkus/redisson-quarkus-16/integration-tests/src/main/resources/application.properties +++ b/redisson-quarkus/redisson-quarkus-16/integration-tests/src/main/resources/application.properties @@ -3,4 +3,4 @@ quarkus.redisson.single-server-config.password=null #quarkus.redisson.cluster-servers-config.nodeAddresses=redis://127.0.0.1:7004,redis://127.0.0.1:7001 #quarkus.redisson.cluster-servers-config.password=null quarkus.redisson.threads=16 -quarkus.redisson.codec=org.redisson.codec.MarshallingCodec \ No newline at end of file +quarkus.redisson.codec=org.redisson.codec.Kryo5Codec \ No newline at end of file diff --git a/redisson-quarkus/redisson-quarkus-20/deployment/src/main/java/io/quarkus/redisson/client/deployment/QuarkusRedissonClientProcessor.java b/redisson-quarkus/redisson-quarkus-20/deployment/src/main/java/io/quarkus/redisson/client/deployment/QuarkusRedissonClientProcessor.java index b4a69f40a..ac966d61a 100644 --- a/redisson-quarkus/redisson-quarkus-20/deployment/src/main/java/io/quarkus/redisson/client/deployment/QuarkusRedissonClientProcessor.java +++ b/redisson-quarkus/redisson-quarkus-20/deployment/src/main/java/io/quarkus/redisson/client/deployment/QuarkusRedissonClientProcessor.java @@ -64,8 +64,7 @@ class QuarkusRedissonClientProcessor { nativeResources.produce(new NativeImageResourceBuildItem("META-INF/services/org.jboss.marshalling.ProviderDescriptor")); watchedFiles.produce(new HotDeploymentWatchedFileBuildItem("redisson.yaml")); - reflectiveItems.produce(new ReflectiveClassBuildItem(false, false, "org.redisson.codec.MarshallingCodec")); - reflectiveItems.produce(new ReflectiveClassBuildItem(false, false, "org.jboss.marshalling.river.RiverProviderDescriptor")); + reflectiveItems.produce(new ReflectiveClassBuildItem(false, false, "org.redisson.codec.Kryo5Codec")); reflectiveItems.produce(new ReflectiveClassBuildItem(true, false, "org.redisson.executor.RemoteExecutorService")); reflectiveItems.produce(new ReflectiveClassBuildItem(true, false, "org.redisson.executor.RemoteExecutorServiceAsync")); diff --git a/redisson-quarkus/redisson-quarkus-20/integration-tests/src/main/resources/application.properties b/redisson-quarkus/redisson-quarkus-20/integration-tests/src/main/resources/application.properties index 3d20bb524..af4e01f47 100644 --- a/redisson-quarkus/redisson-quarkus-20/integration-tests/src/main/resources/application.properties +++ b/redisson-quarkus/redisson-quarkus-20/integration-tests/src/main/resources/application.properties @@ -3,4 +3,4 @@ quarkus.redisson.single-server-config.password=null #quarkus.redisson.cluster-servers-config.nodeAddresses=redis://127.0.0.1:7004,redis://127.0.0.1:7001 #quarkus.redisson.cluster-servers-config.password=null quarkus.redisson.threads=16 -quarkus.redisson.codec=org.redisson.codec.MarshallingCodec \ No newline at end of file +quarkus.redisson.codec=org.redisson.codec.Kryo5Codec \ No newline at end of file diff --git a/redisson-spring-boot-starter/README.md b/redisson-spring-boot-starter/README.md index 285966530..3a96e7471 100644 --- a/redisson-spring-boot-starter/README.md +++ b/redisson-spring-boot-starter/README.md @@ -101,7 +101,7 @@ spring: tcpNoDelay: false threads: 16 nettyThreads: 32 - codec: ! {} + codec: ! {} transportMode: "NIO" ``` diff --git a/redisson/pom.xml b/redisson/pom.xml index 313021ba7..2fd31ea69 100644 --- a/redisson/pom.xml +++ b/redisson/pom.xml @@ -187,11 +187,15 @@ org.jboss.marshalling jboss-marshalling 2.0.11.Final + provided + true org.jboss.marshalling jboss-marshalling-river 2.0.11.Final + provided + true org.msgpack @@ -213,13 +217,17 @@ 2.57 provided true + + + org.objenesis + objenesis + + com.esotericsoftware kryo 5.3.0 - provided - true org.slf4j diff --git a/redisson/src/main/java/org/redisson/codec/Kryo5Codec.java b/redisson/src/main/java/org/redisson/codec/Kryo5Codec.java index 72fe01f95..c9e8efaf8 100644 --- a/redisson/src/main/java/org/redisson/codec/Kryo5Codec.java +++ b/redisson/src/main/java/org/redisson/codec/Kryo5Codec.java @@ -24,6 +24,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufInputStream; import io.netty.buffer.ByteBufOutputStream; +import org.objenesis.strategy.StdInstantiatorStrategy; import org.redisson.client.codec.BaseCodec; import org.redisson.client.handler.State; import org.redisson.client.protocol.Decoder; @@ -82,6 +83,7 @@ public class Kryo5Codec extends BaseCodec { if (classLoader != null) { kryo.setClassLoader(classLoader); } + kryo.setInstantiatorStrategy(new StdInstantiatorStrategy()); kryo.setRegistrationRequired(false); kryo.setReferences(false); kryo.addDefaultSerializer(Throwable.class, new JavaSerializer()); diff --git a/redisson/src/main/java/org/redisson/codec/LZ4Codec.java b/redisson/src/main/java/org/redisson/codec/LZ4Codec.java index 1b5e5c1a9..15e16d753 100644 --- a/redisson/src/main/java/org/redisson/codec/LZ4Codec.java +++ b/redisson/src/main/java/org/redisson/codec/LZ4Codec.java @@ -15,31 +15,30 @@ */ package org.redisson.codec; -import java.io.IOException; -import java.nio.ByteBuffer; - +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; +import net.jpountz.lz4.LZ4Compressor; +import net.jpountz.lz4.LZ4Factory; +import net.jpountz.lz4.LZ4SafeDecompressor; import org.redisson.client.codec.BaseCodec; import org.redisson.client.codec.Codec; import org.redisson.client.handler.State; import org.redisson.client.protocol.Decoder; import org.redisson.client.protocol.Encoder; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; -import net.jpountz.lz4.LZ4Compressor; -import net.jpountz.lz4.LZ4Factory; -import net.jpountz.lz4.LZ4SafeDecompressor; +import java.io.IOException; +import java.nio.ByteBuffer; /** * LZ4 compression codec. * Uses inner Codec to convert object to binary stream. - * MarshallingCodec used by default. + * Kryo5Codec used by default. * * Fully thread-safe. * * https://github.com/jpountz/lz4-java * - * @see org.redisson.codec.MarshallingCodec + * @see org.redisson.codec.Kryo5Codec * * @author Nikita Koksharov * @@ -52,7 +51,7 @@ public class LZ4Codec extends BaseCodec { private final Codec innerCodec; public LZ4Codec() { - this(new MarshallingCodec()); + this(new Kryo5Codec()); } public LZ4Codec(Codec innerCodec) { @@ -60,7 +59,7 @@ public class LZ4Codec extends BaseCodec { } public LZ4Codec(ClassLoader classLoader) { - this(new MarshallingCodec(classLoader)); + this(new Kryo5Codec(classLoader)); } public LZ4Codec(ClassLoader classLoader, LZ4Codec codec) throws ReflectiveOperationException { diff --git a/redisson/src/main/java/org/redisson/codec/SnappyCodec.java b/redisson/src/main/java/org/redisson/codec/SnappyCodec.java index 1dc812cd1..996180baa 100644 --- a/redisson/src/main/java/org/redisson/codec/SnappyCodec.java +++ b/redisson/src/main/java/org/redisson/codec/SnappyCodec.java @@ -48,7 +48,7 @@ public class SnappyCodec extends BaseCodec { private final Codec innerCodec; public SnappyCodec() { - this(new MarshallingCodec()); + this(new Kryo5Codec()); } public SnappyCodec(Codec innerCodec) { @@ -56,7 +56,7 @@ public class SnappyCodec extends BaseCodec { } public SnappyCodec(ClassLoader classLoader) { - this(new MarshallingCodec(classLoader)); + this(new Kryo5Codec(classLoader)); } public SnappyCodec(ClassLoader classLoader, SnappyCodec codec) throws ReflectiveOperationException { diff --git a/redisson/src/main/java/org/redisson/codec/SnappyCodecV2.java b/redisson/src/main/java/org/redisson/codec/SnappyCodecV2.java index 53ac0662c..d8f47e1d5 100644 --- a/redisson/src/main/java/org/redisson/codec/SnappyCodecV2.java +++ b/redisson/src/main/java/org/redisson/codec/SnappyCodecV2.java @@ -29,13 +29,13 @@ import java.io.IOException; /** * Google's Snappy compression codec. * Uses inner Codec to convert object to binary stream. - * MarshallingCodec used by default. + * Kryo5Codec used by default. *

* Based on https://github.com/xerial/snappy-java * * Fully thread-safe. * - * @see org.redisson.codec.MarshallingCodec + * @see org.redisson.codec.Kryo5Codec * * @author Nikita Koksharov * @@ -45,7 +45,7 @@ public class SnappyCodecV2 extends BaseCodec { private final Codec innerCodec; public SnappyCodecV2() { - this(new MarshallingCodec()); + this(new Kryo5Codec()); } public SnappyCodecV2(Codec innerCodec) { @@ -53,7 +53,7 @@ public class SnappyCodecV2 extends BaseCodec { } public SnappyCodecV2(ClassLoader classLoader) { - this(new MarshallingCodec(classLoader)); + this(new Kryo5Codec(classLoader)); } public SnappyCodecV2(ClassLoader classLoader, SnappyCodecV2 codec) throws ReflectiveOperationException { diff --git a/redisson/src/main/java/org/redisson/config/Config.java b/redisson/src/main/java/org/redisson/config/Config.java index 957bc6d67..a38596be3 100644 --- a/redisson/src/main/java/org/redisson/config/Config.java +++ b/redisson/src/main/java/org/redisson/config/Config.java @@ -19,7 +19,7 @@ import io.netty.channel.EventLoopGroup; import org.redisson.client.DefaultNettyHook; import org.redisson.client.NettyHook; import org.redisson.client.codec.Codec; -import org.redisson.codec.MarshallingCodec; +import org.redisson.codec.Kryo5Codec; import org.redisson.connection.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -101,7 +101,7 @@ public class Config { if (oldConf.getCodec() == null) { // use it by default - oldConf.setCodec(new MarshallingCodec()); + oldConf.setCodec(new Kryo5Codec()); } setConnectionListener(oldConf.getConnectionListener()); @@ -159,10 +159,10 @@ public class Config { } /** - * Redis data codec. Default is MarshallingCodec codec + * Redis data codec. Default is Kryo5Codec codec * * @see org.redisson.client.codec.Codec - * @see org.redisson.codec.MarshallingCodec + * @see org.redisson.codec.Kryo5Codec * * @param codec object * @return config diff --git a/redisson/src/test/java/org/redisson/RedissonBucketTest.java b/redisson/src/test/java/org/redisson/RedissonBucketTest.java index 71d04c793..dbe00d171 100755 --- a/redisson/src/test/java/org/redisson/RedissonBucketTest.java +++ b/redisson/src/test/java/org/redisson/RedissonBucketTest.java @@ -187,7 +187,7 @@ public class RedissonBucketTest extends BaseTest { Assumptions.assumeTrue(RedisRunner.getDefaultRedisServerInstance().getRedisVersion().compareTo("4.0.0") > 0); RBucket al = redisson.getBucket("test"); al.set(1234); - assertThat(al.sizeInMemory()).isEqualTo(56); + assertThat(al.sizeInMemory()).isEqualTo(51); } @Test @@ -240,7 +240,7 @@ public class RedissonBucketTest extends BaseTest { assertThat(bucket.size()).isZero(); bucket.set("1234"); // json adds quotes - assertThat(bucket.size()).isEqualTo(7); + assertThat(bucket.size()).isEqualTo(5); } @Test diff --git a/redisson/src/test/java/org/redisson/RedissonQueueTest.java b/redisson/src/test/java/org/redisson/RedissonQueueTest.java index 9cda0b9d0..b55b418ec 100644 --- a/redisson/src/test/java/org/redisson/RedissonQueueTest.java +++ b/redisson/src/test/java/org/redisson/RedissonQueueTest.java @@ -2,10 +2,14 @@ package org.redisson; import static org.assertj.core.api.Assertions.assertThat; +import java.io.Serializable; import java.util.Arrays; import java.util.List; import java.util.NoSuchElementException; +import java.util.UUID; +import avro.shaded.com.google.common.base.Objects; +import org.jboss.marshalling.reflect.SerializableClassRegistry; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.redisson.api.RQueue; @@ -42,6 +46,32 @@ public class RedissonQueueTest extends BaseTest { Assertions.assertEquals((Integer)2, queue.element()); } + public static class TestModel { + private String key; + private String traceId; + private long createdAt; + private UUID uuid = UUID.randomUUID(); + + public TestModel() { + } + + public TestModel(String key, String traceId, long createdAt) { + this.key = key; + this.traceId = traceId; + this.createdAt = createdAt; + } + + } + + @Test + public void testRemoveWithCodec() { + RQueue queue = redisson.getQueue("queue"); + + TestModel msg = new TestModel("key", "traceId", 0L); + queue.add(msg); + assertThat(queue.contains(queue.peek())).isTrue(); + } + @Test public void testRemove() { RQueue queue = getQueue(); From e912e98cfe1884903fdc0d2e883c280dcf36aef6 Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Tue, 6 Dec 2022 14:46:27 +0300 Subject: [PATCH 08/58] refactoring --- .../native-image/org.redisson/redisson/resource-config.json | 1 - 1 file changed, 1 deletion(-) diff --git a/redisson-all/src/main/resources/META-INF/native-image/org.redisson/redisson/resource-config.json b/redisson-all/src/main/resources/META-INF/native-image/org.redisson/redisson/resource-config.json index 8c00d0c5e..dc809a11a 100644 --- a/redisson-all/src/main/resources/META-INF/native-image/org.redisson/redisson/resource-config.json +++ b/redisson-all/src/main/resources/META-INF/native-image/org.redisson/redisson/resource-config.json @@ -2,7 +2,6 @@ "resources":{ "includes":[ {"pattern":"\\QMETA-INF/MANIFEST.MF\\E"}, - {"pattern":"\\QMETA-INF/services/org.jboss.marshalling.ProviderDescriptor\\E"} ]}, "bundles":[] } From 2dbb5a82514476a914f6fcbd9a83ab395775f4fa Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Tue, 6 Dec 2022 20:09:08 +0300 Subject: [PATCH 09/58] Update README.md --- redisson-quarkus/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redisson-quarkus/README.md b/redisson-quarkus/README.md index 070665ea8..802cbad49 100644 --- a/redisson-quarkus/README.md +++ b/redisson-quarkus/README.md @@ -66,7 +66,7 @@ Config structure is a flat Redisson YAML configuration - NOTE: Setting names in camel case should be joined with hyphens (-). -Below is the configuration for Redisson in single mode. +Below is example for Redisson in single mode. ``` quarkus.redisson.single-server-config.address=redis://localhost:6379 quarkus.redisson.single-server-config.password=null From 3c4db93f147ecbb978c7bdfc32b22f69aceaf8e9 Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Tue, 6 Dec 2022 20:09:25 +0300 Subject: [PATCH 10/58] Update README.md --- redisson-quarkus/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redisson-quarkus/README.md b/redisson-quarkus/README.md index 802cbad49..40512c3dc 100644 --- a/redisson-quarkus/README.md +++ b/redisson-quarkus/README.md @@ -66,7 +66,7 @@ Config structure is a flat Redisson YAML configuration - NOTE: Setting names in camel case should be joined with hyphens (-). -Below is example for Redisson in single mode. +Below is configuration example for Redisson in single mode. ``` quarkus.redisson.single-server-config.address=redis://localhost:6379 quarkus.redisson.single-server-config.password=null From 708fb7b4dee2f26c8e0bb41548210da116630408 Mon Sep 17 00:00:00 2001 From: Noel Vo Date: Thu, 8 Dec 2022 21:15:13 -0500 Subject: [PATCH 11/58] Fix incorrectly reset jackson type factory Signed-off-by: Noel Vo --- redisson/src/main/java/org/redisson/codec/JsonJacksonCodec.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redisson/src/main/java/org/redisson/codec/JsonJacksonCodec.java b/redisson/src/main/java/org/redisson/codec/JsonJacksonCodec.java index 4c31306e5..81b0c237e 100755 --- a/redisson/src/main/java/org/redisson/codec/JsonJacksonCodec.java +++ b/redisson/src/main/java/org/redisson/codec/JsonJacksonCodec.java @@ -130,7 +130,7 @@ public class JsonJacksonCodec extends BaseCodec { } protected static ObjectMapper createObjectMapper(ClassLoader classLoader, ObjectMapper om) { - TypeFactory tf = TypeFactory.defaultInstance().withClassLoader(classLoader); + TypeFactory tf = om.getTypeFactory().withClassLoader(classLoader); om.setTypeFactory(tf); return om; } From e8c91bf8a1f9b36d1ce5a845e4e162aeb411de92 Mon Sep 17 00:00:00 2001 From: Jordan Merrick Date: Fri, 9 Dec 2022 13:43:24 -0500 Subject: [PATCH 12/58] Fixed - RedissonFunction doesn't pass keys to Redis correctly Signed-off-by: Jordan Merrick --- .../main/java/org/redisson/RedissonFuction.java | 2 +- .../java/org/redisson/RedissonFunctionTest.java | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/redisson/src/main/java/org/redisson/RedissonFuction.java b/redisson/src/main/java/org/redisson/RedissonFuction.java index 8d40d638a..749bc7dc4 100644 --- a/redisson/src/main/java/org/redisson/RedissonFuction.java +++ b/redisson/src/main/java/org/redisson/RedissonFuction.java @@ -199,7 +199,7 @@ public class RedissonFuction implements RFunction { args.add(name); args.add(keys.size()); if (keys.size() > 0) { - args.add(keys); + args.addAll(keys); } args.addAll(encode(Arrays.asList(values), codec)); if (mode == FunctionMode.READ) { diff --git a/redisson/src/test/java/org/redisson/RedissonFunctionTest.java b/redisson/src/test/java/org/redisson/RedissonFunctionTest.java index b285f6644..f4aaea23a 100644 --- a/redisson/src/test/java/org/redisson/RedissonFunctionTest.java +++ b/redisson/src/test/java/org/redisson/RedissonFunctionTest.java @@ -67,6 +67,20 @@ public class RedissonFunctionTest extends BaseTest { assertThat(s3).isEqualTo(123L); } + @Test + public void testKeysLoadAsExpected() { + RFunction f = redisson.getFunction(); + f.flush(); + f.load("lib", "redis.register_function('myfun', function(keys, args) return keys[1] end)" + + "redis.register_function('myfun2', function(keys, args) return args[1] end"); + String s = f.call(FunctionMode.READ, "myfun", FunctionResult.VALUE, List.of("testKey"), "arg1"); + assertThat(s).isEqualTo("testKey"); + + RFunction f2 = redisson.getFunction(StringCodec.INSTANCE); + String s2 = f2.call(FunctionMode.READ, "myfun2", FunctionResult.STRING, List.of("testKey1", "testKey2"), "arg1"); + assertThat(s2).isEqualTo("arg1"); + } + @Test public void testList() { RFunction f = redisson.getFunction(); From 0e5c759602e69efc2a908552721313cb3238c45d Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Mon, 12 Dec 2022 10:01:30 +0300 Subject: [PATCH 13/58] Fixed - CommandDecoder.messageDecoder() method throws NPE if RBatch object used with executionMode = IN_MEMORY. (regression since 3.18.1) #4725 --- .../main/java/org/redisson/client/handler/CommandDecoder.java | 2 +- redisson/src/main/java/org/redisson/command/RedisExecutor.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/redisson/src/main/java/org/redisson/client/handler/CommandDecoder.java b/redisson/src/main/java/org/redisson/client/handler/CommandDecoder.java index e5f5e5574..4e177211b 100644 --- a/redisson/src/main/java/org/redisson/client/handler/CommandDecoder.java +++ b/redisson/src/main/java/org/redisson/client/handler/CommandDecoder.java @@ -98,7 +98,7 @@ public class CommandDecoder extends ReplayingDecoder { } } } else { - if (!holder.getChannelPromise().isSuccess()) { + if (holder.getChannelPromise().isDone() && !holder.getChannelPromise().isSuccess()) { sendNext(ctx.channel()); // throw REPLAY error in.indexOf(Integer.MAX_VALUE/2, Integer.MAX_VALUE, (byte) 0); diff --git a/redisson/src/main/java/org/redisson/command/RedisExecutor.java b/redisson/src/main/java/org/redisson/command/RedisExecutor.java index a36c554ae..13b2185ff 100644 --- a/redisson/src/main/java/org/redisson/command/RedisExecutor.java +++ b/redisson/src/main/java/org/redisson/command/RedisExecutor.java @@ -187,7 +187,7 @@ public class RedisExecutor { TimerTask task = timeout -> { if (connectionFuture.cancel(false)) { exception = new RedisTimeoutException("Unable to acquire connection! " + this.connectionFuture + - "Increase connection pool size. " + "Increase connection pool size or timeout. " + "Node source: " + source + ", command: " + LogHelper.toString(command, params) + " after " + attempt + " retry attempts"); From 95fe0bdc2fa6b5e791e2975af3d2ff5ee13928ac Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Mon, 12 Dec 2022 10:02:15 +0300 Subject: [PATCH 14/58] Fixed - RBatch with executionMode = REDIS_WRITE_ATOMIC throws NPE in case of connection starvation. --- .../org/redisson/command/RedisQueuedBatchExecutor.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/redisson/src/main/java/org/redisson/command/RedisQueuedBatchExecutor.java b/redisson/src/main/java/org/redisson/command/RedisQueuedBatchExecutor.java index 55d02cc22..aae353937 100644 --- a/redisson/src/main/java/org/redisson/command/RedisQueuedBatchExecutor.java +++ b/redisson/src/main/java/org/redisson/command/RedisQueuedBatchExecutor.java @@ -198,15 +198,16 @@ public class RedisQueuedBatchExecutor extends BaseRedisBatchExecutor if (entry.getConnectionFuture() != null) { - return entry.getConnectionFuture(); + connectionFuture = entry.getConnectionFuture(); + return connectionFuture; } synchronized (this) { if (entry.getConnectionFuture() != null) { - return entry.getConnectionFuture(); + connectionFuture = entry.getConnectionFuture(); + return connectionFuture; } - CompletableFuture connectionFuture; if (this.options.getExecutionMode() == ExecutionMode.REDIS_WRITE_ATOMIC) { connectionFuture = connectionManager.connectionWriteOp(source, null); } else { From d8190cee5fb099e7973bffe1d4535e45aa5ce9cf Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Mon, 12 Dec 2022 10:34:46 +0300 Subject: [PATCH 15/58] test fixed --- .../src/test/java/org/redisson/RedissonFunctionTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/redisson/src/test/java/org/redisson/RedissonFunctionTest.java b/redisson/src/test/java/org/redisson/RedissonFunctionTest.java index f4aaea23a..efa77046f 100644 --- a/redisson/src/test/java/org/redisson/RedissonFunctionTest.java +++ b/redisson/src/test/java/org/redisson/RedissonFunctionTest.java @@ -7,6 +7,7 @@ import org.redisson.api.*; import org.redisson.client.codec.LongCodec; import org.redisson.client.codec.StringCodec; +import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -73,11 +74,11 @@ public class RedissonFunctionTest extends BaseTest { f.flush(); f.load("lib", "redis.register_function('myfun', function(keys, args) return keys[1] end)" + "redis.register_function('myfun2', function(keys, args) return args[1] end"); - String s = f.call(FunctionMode.READ, "myfun", FunctionResult.VALUE, List.of("testKey"), "arg1"); + String s = f.call(FunctionMode.READ, "myfun", FunctionResult.VALUE, Arrays.asList("testKey"), "arg1"); assertThat(s).isEqualTo("testKey"); RFunction f2 = redisson.getFunction(StringCodec.INSTANCE); - String s2 = f2.call(FunctionMode.READ, "myfun2", FunctionResult.STRING, List.of("testKey1", "testKey2"), "arg1"); + String s2 = f2.call(FunctionMode.READ, "myfun2", FunctionResult.STRING, Arrays.asList("testKey1", "testKey2"), "arg1"); assertThat(s2).isEqualTo("arg1"); } From b172cd81182142f00cf5f4760df0ed0b52841647 Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Mon, 12 Dec 2022 14:34:59 +0300 Subject: [PATCH 16/58] Fixed - most of pubsub subscriptions fail to resubscribe after failover. #4731 --- .../cluster/ClusterConnectionManager.java | 3 +- .../pubsub/PublishSubscribeService.java | 41 ++-- .../java/org/redisson/RedissonTopicTest.java | 177 +++++++++++++++++- 3 files changed, 197 insertions(+), 24 deletions(-) diff --git a/redisson/src/main/java/org/redisson/cluster/ClusterConnectionManager.java b/redisson/src/main/java/org/redisson/cluster/ClusterConnectionManager.java index 18212b7ab..3267386e1 100644 --- a/redisson/src/main/java/org/redisson/cluster/ClusterConnectionManager.java +++ b/redisson/src/main/java/org/redisson/cluster/ClusterConnectionManager.java @@ -244,7 +244,6 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager { private void shutdownEntry(MasterSlaveEntry entry) { if (entry != null && entry.decReference() == 0) { - client2entry.remove(entry.getClient()); entry.getAllEntries().forEach(e -> { RedisURI uri = new RedisURI(e.getClient().getConfig().getAddress().getScheme(), e.getClient().getAddr().getAddress().getHostAddress(), @@ -260,6 +259,8 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager { entry.getClient().getAddr().getPort()); disconnectNode(uri); + client2entry.remove(entry.getClient()); + String slaves = entry.getAllEntries().stream() .filter(e -> !e.getClient().getAddr().equals(entry.getClient().getAddr())) .map(e -> e.getClient().toString()) diff --git a/redisson/src/main/java/org/redisson/pubsub/PublishSubscribeService.java b/redisson/src/main/java/org/redisson/pubsub/PublishSubscribeService.java index 64f4d1a66..f78e38a23 100644 --- a/redisson/src/main/java/org/redisson/pubsub/PublishSubscribeService.java +++ b/redisson/src/main/java/org/redisson/pubsub/PublishSubscribeService.java @@ -74,14 +74,8 @@ public class PublishSubscribeService { public static class PubSubEntry { - Set keys = Collections.newSetFromMap(new ConcurrentHashMap<>()); - Queue entries = new ConcurrentLinkedQueue<>(); - public Set getKeys() { - return keys; - } - public Queue getEntries() { return entries; } @@ -581,27 +575,30 @@ public class PublishSubscribeService { } public void reattachPubSub(RedisPubSubConnection redisPubSubConnection) { - for (Map.Entry e : entry2PubSubConnection.entrySet()) { - for (PubSubConnectionEntry entry : e.getValue().getEntries()) { - if (!entry.getConnection().equals(redisPubSubConnection)) { - continue; - } - - freePubSubLock.acquire().thenAccept(r -> { - e.getValue().getEntries().remove(entry); - freePubSubLock.release(); - }); + MasterSlaveEntry en = connectionManager.getEntry(redisPubSubConnection.getRedisClient()); + if (en == null) { + return; + } - reattachPubSubListeners(redisPubSubConnection.getChannels().keySet(), e.getKey(), entry, PubSubType.UNSUBSCRIBE); - reattachPubSubListeners(redisPubSubConnection.getShardedChannels().keySet(), e.getKey(), entry, PubSubType.SUNSUBSCRIBE); - reattachPubSubListeners(redisPubSubConnection.getPatternChannels().keySet(), e.getKey(), entry, PubSubType.PUNSUBSCRIBE); - return; + freePubSubLock.acquire().thenAccept(r -> { + try { + PubSubEntry ee = entry2PubSubConnection.get(en); + if (ee != null) { + ee.getEntries().removeIf(e -> e.getConnection().equals(redisPubSubConnection)); + } + } finally { + freePubSubLock.release(); } - } + }); + + reattachPubSubListeners(redisPubSubConnection.getChannels().keySet(), en, PubSubType.UNSUBSCRIBE); + reattachPubSubListeners(redisPubSubConnection.getShardedChannels().keySet(), en, PubSubType.SUNSUBSCRIBE); + reattachPubSubListeners(redisPubSubConnection.getPatternChannels().keySet(), en, PubSubType.PUNSUBSCRIBE); } - private void reattachPubSubListeners(Set channels, MasterSlaveEntry en, PubSubConnectionEntry entry, PubSubType topicType) { + private void reattachPubSubListeners(Set channels, MasterSlaveEntry en, PubSubType topicType) { for (ChannelName channelName : channels) { + PubSubConnectionEntry entry = name2PubSubConnection.get(new PubSubKey(channelName, en)); Collection> listeners = entry.getListeners(channelName); CompletableFuture subscribeCodecFuture = unsubscribe(channelName, en, topicType); if (listeners.isEmpty()) { diff --git a/redisson/src/test/java/org/redisson/RedissonTopicTest.java b/redisson/src/test/java/org/redisson/RedissonTopicTest.java index 225c77aee..55d1b849e 100644 --- a/redisson/src/test/java/org/redisson/RedissonTopicTest.java +++ b/redisson/src/test/java/org/redisson/RedissonTopicTest.java @@ -1371,7 +1371,182 @@ public class RedissonTopicTest { redisson.shutdown(); process.shutdown(); } - + + @Test + public void testReattachInSentinel3() throws Exception { + RedisRunner.RedisProcess master = new RedisRunner() + .nosave() + .randomDir() + .port(6400) + .run(); + + RedisRunner.RedisProcess slave1 = new RedisRunner() + .port(6380) + .nosave() + .randomDir() + .slaveof("127.0.0.1", 6400) + .run(); + + RedisRunner.RedisProcess sentinel1 = new RedisRunner() + .nosave() + .randomDir() + .port(26379) + .sentinel() + .sentinelMonitor("myMaster", "127.0.0.1", 6400, 2) + .sentinelDownAfterMilliseconds("myMaster", 750) + .sentinelFailoverTimeout("myMaster", 1250) + .run(); + + RedisRunner.RedisProcess sentinel2 = new RedisRunner() + .nosave() + .randomDir() + .port(26380) + .sentinel() + .sentinelMonitor("myMaster", "127.0.0.1", 6400, 2) + .sentinelDownAfterMilliseconds("myMaster", 750) + .sentinelFailoverTimeout("myMaster", 1250) + .run(); + + RedisRunner.RedisProcess sentinel3 = new RedisRunner() + .nosave() + .randomDir() + .port(26381) + .sentinel() + .sentinelMonitor("myMaster", "127.0.0.1", 6400, 2) + .sentinelDownAfterMilliseconds("myMaster", 750) + .sentinelFailoverTimeout("myMaster", 1250) + .run(); + + Thread.sleep(1000); + + Config config = new Config(); + config.useSentinelServers() + .addSentinelAddress(sentinel3.getRedisServerAddressAndPort()).setMasterName("myMaster") + .setSubscriptionsPerConnection(20) + .setSubscriptionConnectionPoolSize(200); + RedissonClient redisson = Redisson.create(config); + + ScheduledExecutorService executor1 = Executors.newScheduledThreadPool(5); + + AtomicBoolean exceptionDetected = new AtomicBoolean(false); + + Deque status = new ConcurrentLinkedDeque<>(); + Runnable rLockPayload = + () -> { + try { + Integer randomLock = ThreadLocalRandom.current().nextInt(100); + RLock lock = redisson.getLock(randomLock.toString()); + lock.lock(10, TimeUnit.SECONDS); + lock.unlock(); + + RTopic t = redisson.getTopic("topic_" + randomLock); + int s = t.addListener(new StatusListener() { + @Override + public void onSubscribe(String channel) { + } + + @Override + public void onUnsubscribe(String channel) { + } + }); + t.removeListener(s); + + status.add("ok"); + } catch (Exception e) { + status.add("failed"); + if (e.getCause().getMessage().contains("slaves were synced")) { + return; + } + e.printStackTrace(); + exceptionDetected.set(true); + } + }; + + executor1.scheduleAtFixedRate(rLockPayload, 100, 50, TimeUnit.MILLISECONDS); + executor1.scheduleAtFixedRate(rLockPayload, 100, 50, TimeUnit.MILLISECONDS); + executor1.scheduleAtFixedRate(rLockPayload, 100, 50, TimeUnit.MILLISECONDS); + executor1.scheduleAtFixedRate(rLockPayload, 100, 50, TimeUnit.MILLISECONDS); + executor1.scheduleAtFixedRate(rLockPayload, 100, 50, TimeUnit.MILLISECONDS); + + Thread.sleep(java.time.Duration.ofSeconds(10).toMillis()); + + master.stop(); + + Thread.sleep(TimeUnit.SECONDS.toMillis(30)); + + assertThat(exceptionDetected.get()).isFalse(); + assertThat(status.peekLast()).isEqualTo("ok"); + + executor1.shutdown(); + + redisson.shutdown(); + sentinel1.stop(); + sentinel2.stop(); + sentinel3.stop(); + master.stop(); + slave1.stop(); + } + + @Test + public void testReattachInClusterMaster2() throws Exception { + RedisRunner master1 = new RedisRunner().port(6890).randomDir().nosave(); + RedisRunner master2 = new RedisRunner().port(6891).randomDir().nosave(); + RedisRunner master3 = new RedisRunner().port(6892).randomDir().nosave(); + RedisRunner slave1 = new RedisRunner().port(6900).randomDir().nosave(); + RedisRunner slave2 = new RedisRunner().port(6901).randomDir().nosave(); + RedisRunner slave3 = new RedisRunner().port(6902).randomDir().nosave(); + + ClusterRunner clusterRunner = new ClusterRunner() + .addNode(master1, slave1) + .addNode(master2, slave2) + .addNode(master3, slave3); + ClusterProcesses process = clusterRunner.run(); + + Config config = new Config(); + config.useClusterServers() + .addNodeAddress(process.getNodes().stream().findAny().get().getRedisServerAddressAndPort()); + RedissonClient redisson = Redisson.create(config); + + Queue messages = new ConcurrentLinkedQueue<>(); + Queue subscriptions = new ConcurrentLinkedQueue<>(); + + int topicsAmount = 100; + for (int i = 0; i < topicsAmount; i++) { + RTopic topic = redisson.getTopic("topic" + i); + int finalI = i; + topic.addListener(new StatusListener() { + + @Override + public void onUnsubscribe(String channel) { + } + + @Override + public void onSubscribe(String channel) { + subscriptions.add("topic" + finalI); + } + }); + topic.addListener(String.class, (channel, msg) -> messages.add(msg)); + } + + RedisRunner.RedisProcess master = process.getNodes().stream().filter(x -> x.getRedisServerPort() == master1.getPort()).findFirst().get(); + master.stop(); + + Thread.sleep(TimeUnit.SECONDS.toMillis(30)); + + assertThat(subscriptions).hasSize(140); + + for (int i = 0; i < topicsAmount; i++) { + RTopic topic = redisson.getTopic("topic" + i); + topic.publish("topic" + i); + } + + Thread.sleep(100); + assertThat(messages).hasSize(topicsAmount); + + redisson.shutdown(); + process.shutdown(); + } + @Test public void testReattachInClusterMaster() throws Exception { RedisRunner master1 = new RedisRunner().randomPort().randomDir().nosave(); From 19f7223033b587aea6bc512bc26dd4ffb1fc8795 Mon Sep 17 00:00:00 2001 From: Vladimir Tarasov Date: Mon, 12 Dec 2022 16:55:27 +0500 Subject: [PATCH 17/58] Use slf4j late-binding when logging instead of string concat Signed-off-by: Vladimir Tarasov --- .../java/org/redisson/MapWriteBehindTask.java | 8 +-- .../java/org/redisson/RedissonBaseLock.java | 2 +- .../main/java/org/redisson/RedissonMap.java | 6 +-- .../main/java/org/redisson/RedissonNode.java | 2 +- .../org/redisson/RedissonReliableTopic.java | 2 +- .../org/redisson/RedissonRemoteService.java | 12 ++--- .../src/main/java/org/redisson/Version.java | 2 +- .../org/redisson/client/RedisConnection.java | 2 +- .../client/handler/CommandDecoder.java | 4 +- .../client/handler/CommandPubSubDecoder.java | 4 +- .../client/handler/ErrorsLoggingHandler.java | 2 +- .../client/handler/PingConnectionHandler.java | 2 +- .../cluster/ClusterConnectionManager.java | 11 ++-- .../redisson/command/CommandBatchService.java | 2 +- .../org/redisson/connection/DNSMonitor.java | 6 +-- .../MasterSlaveConnectionManager.java | 6 +-- .../redisson/connection/MasterSlaveEntry.java | 2 +- .../ReplicatedConnectionManager.java | 7 ++- .../connection/SentinelConnectionManager.java | 10 ++-- .../balancer/LoadBalancerManager.java | 4 +- .../connection/pool/ConnectionPool.java | 4 +- .../org/redisson/eviction/EvictionTask.java | 2 +- .../RedissonExecutorRemoteService.java | 2 +- .../org/redisson/remote/BaseRemoteProxy.java | 2 +- .../org/redisson/RedissonFairLockTest.java | 52 +++++++++---------- 25 files changed, 78 insertions(+), 80 deletions(-) diff --git a/redisson/src/main/java/org/redisson/MapWriteBehindTask.java b/redisson/src/main/java/org/redisson/MapWriteBehindTask.java index 63741afeb..9481cc11d 100644 --- a/redisson/src/main/java/org/redisson/MapWriteBehindTask.java +++ b/redisson/src/main/java/org/redisson/MapWriteBehindTask.java @@ -93,7 +93,7 @@ public class MapWriteBehindTask { deletedKeys.clear(); } } catch (Exception exception) { - log.error("Unable to delete keys: " + deletedKeys, exception); + log.error("Unable to delete keys: {}", deletedKeys, exception); } try { if (!addedMap.isEmpty()) { @@ -105,7 +105,7 @@ public class MapWriteBehindTask { addedMap.clear(); } } catch (Exception exception) { - log.error("Unable to add keys: " + addedMap, exception); + log.error("Unable to add keys: {}", addedMap, exception); } } @@ -124,7 +124,7 @@ public class MapWriteBehindTask { } } catch (Exception exception) { - log.error("Unable to delete keys: " + deletedKeys, exception); + log.error("Unable to delete keys: {}", deletedKeys, exception); } } } else { @@ -140,7 +140,7 @@ public class MapWriteBehindTask { addedMap.clear(); } } catch (Exception exception) { - log.error("Unable to add keys: " + addedMap, exception); + log.error("Unable to add keys: {}", addedMap, exception); } } } diff --git a/redisson/src/main/java/org/redisson/RedissonBaseLock.java b/redisson/src/main/java/org/redisson/RedissonBaseLock.java index 4a521bf54..02146635a 100644 --- a/redisson/src/main/java/org/redisson/RedissonBaseLock.java +++ b/redisson/src/main/java/org/redisson/RedissonBaseLock.java @@ -140,7 +140,7 @@ public abstract class RedissonBaseLock extends RedissonExpirable implements RLoc CompletionStage future = renewExpirationAsync(threadId); future.whenComplete((res, e) -> { if (e != null) { - log.error("Can't update lock " + getRawName() + " expiration", e); + log.error("Can't update lock {} expiration", getRawName(), e); EXPIRATION_RENEWAL_MAP.remove(getEntryName()); return; } diff --git a/redisson/src/main/java/org/redisson/RedissonMap.java b/redisson/src/main/java/org/redisson/RedissonMap.java index 9e19d44af..ab7de0127 100644 --- a/redisson/src/main/java/org/redisson/RedissonMap.java +++ b/redisson/src/main/java/org/redisson/RedissonMap.java @@ -1723,7 +1723,7 @@ public class RedissonMap extends RedissonExpirable implements RMap { return; } } catch (Exception e) { - log.error("Unable to load value by key " + key + " for map " + getRawName(), e); + log.error("Unable to load value by key {} for map {}", key, getRawName(), e); lock.unlockAsync(threadId) .whenComplete((r, ex) -> { if (ex != null) { @@ -1765,7 +1765,7 @@ public class RedissonMap extends RedissonExpirable implements RMap { return lock.unlockAsync(threadId); } if (ex != null) { - log.error("Unable to load value by key " + key + " for map " + getRawName(), ex); + log.error("Unable to load value by key {} for map {}", key, getRawName(), ex); return lock.unlockAsync(threadId); } @@ -1776,7 +1776,7 @@ public class RedissonMap extends RedissonExpirable implements RMap { return (CompletionStage) putOperationAsync(key, (V) value).handle((r, ex) -> { RFuture f = lock.unlockAsync(threadId); if (ex != null) { - log.error("Unable to store value by key " + key + " for map " + getRawName(), ex); + log.error("Unable to store value by key {} for map {}", key, getRawName(), ex); return f; } return f.thenApply(res -> value); diff --git a/redisson/src/main/java/org/redisson/RedissonNode.java b/redisson/src/main/java/org/redisson/RedissonNode.java index 911d380a6..dae7b5f4c 100644 --- a/redisson/src/main/java/org/redisson/RedissonNode.java +++ b/redisson/src/main/java/org/redisson/RedissonNode.java @@ -94,7 +94,7 @@ public final class RedissonNode { try { config = RedissonNodeFileConfig.fromYAML(new File(configPath)); } catch (IOException e1) { - log.error("Can't parse json config " + configPath, e); + log.error("Can't parse json config {}", configPath, e); throw new IllegalArgumentException("Can't parse yaml config " + configPath, e1); } } diff --git a/redisson/src/main/java/org/redisson/RedissonReliableTopic.java b/redisson/src/main/java/org/redisson/RedissonReliableTopic.java index 4d06d3d1f..69d6125e8 100644 --- a/redisson/src/main/java/org/redisson/RedissonReliableTopic.java +++ b/redisson/src/main/java/org/redisson/RedissonReliableTopic.java @@ -335,7 +335,7 @@ public class RedissonReliableTopic extends RedissonExpirable implements RReliabl System.currentTimeMillis() + commandExecutor.getConnectionManager().getCfg().getReliableTopicWatchdogTimeout(), subscriberId.get()); future.whenComplete((res, e) -> { if (e != null) { - log.error("Can't update reliable topic " + getRawName() + " expiration time", e); + log.error("Can't update reliable topic {} expiration time", getRawName(), e); return; } diff --git a/redisson/src/main/java/org/redisson/RedissonRemoteService.java b/redisson/src/main/java/org/redisson/RedissonRemoteService.java index 57a0f6862..1fe25c0c8 100644 --- a/redisson/src/main/java/org/redisson/RedissonRemoteService.java +++ b/redisson/src/main/java/org/redisson/RedissonRemoteService.java @@ -280,7 +280,7 @@ public class RedissonRemoteService extends BaseRemoteService implements RRemoteS if (exc instanceof RedissonShutdownException) { return; } - log.error("Can't process the remote service request with id " + requestId, exc); + log.error("Can't process the remote service request with id {}", requestId, exc); // re-subscribe after a failed takeAsync resubscribe(remoteInterface, requestQueue, executor, bean); @@ -330,7 +330,7 @@ public class RedissonRemoteService extends BaseRemoteService implements RRemoteS if (ex instanceof RedissonShutdownException) { return; } - log.error("Can't send ack for request: " + request, ex); + log.error("Can't send ack for request: {}", request, ex); // re-subscribe after a failed send (ack) resubscribe(remoteInterface, requestQueue, executor, bean); @@ -350,7 +350,7 @@ public class RedissonRemoteService extends BaseRemoteService implements RRemoteS if (exce instanceof RedissonShutdownException) { return; } - log.error("Can't send ack for request: " + request, exce); + log.error("Can't send ack for request: {}", request, exce); // re-subscribe after a failed send (ack) resubscribe(remoteInterface, requestQueue, executor, bean); @@ -413,13 +413,13 @@ public class RedissonRemoteService extends BaseRemoteService implements RRemoteS if (exc instanceof RedissonShutdownException) { return; } - log.error("Can't send response: " + response + " for request: " + request, exc); + log.error("Can't send response: {} for request: {}", response, request, exc); } resubscribe(remoteInterface, requestQueue, executor, method.getBean()); }); } catch (Exception ex) { - log.error("Can't send response: " + result + " for request: " + request, ex); + log.error("Can't send response: {} for request: {}", result, request, ex); } } else { resubscribe(remoteInterface, requestQueue, executor, method.getBean()); @@ -465,7 +465,7 @@ public class RedissonRemoteService extends BaseRemoteService implements RRemoteS } catch (Exception e) { RemoteServiceResponse response = new RemoteServiceResponse(request.getId(), e.getCause()); responsePromise.complete(response); - log.error("Can't execute: " + request, e); + log.error("Can't execute: {}", request, e); } if (cancelRequestFuture != null) { diff --git a/redisson/src/main/java/org/redisson/Version.java b/redisson/src/main/java/org/redisson/Version.java index 94b490a56..796e77869 100644 --- a/redisson/src/main/java/org/redisson/Version.java +++ b/redisson/src/main/java/org/redisson/Version.java @@ -38,7 +38,7 @@ public class Version { } String name = attrs.getValue("Bundle-Name"); if ("Redisson".equals(name)) { - log.info("Redisson " + attrs.getValue("Bundle-Version")); + log.info("Redisson {}", attrs.getValue("Bundle-Version")); break; } } diff --git a/redisson/src/main/java/org/redisson/client/RedisConnection.java b/redisson/src/main/java/org/redisson/client/RedisConnection.java index c8d7623ce..2362479a8 100644 --- a/redisson/src/main/java/org/redisson/client/RedisConnection.java +++ b/redisson/src/main/java/org/redisson/client/RedisConnection.java @@ -69,7 +69,7 @@ public class RedisConnection implements RedisCommands { updateChannel(channel); lastUsageTime = System.nanoTime(); - LOG.debug("Connection created " + redisClient); + LOG.debug("Connection created {}", redisClient); } protected RedisConnection(RedisClient redisClient) { diff --git a/redisson/src/main/java/org/redisson/client/handler/CommandDecoder.java b/redisson/src/main/java/org/redisson/client/handler/CommandDecoder.java index 4e177211b..798ee6d1b 100644 --- a/redisson/src/main/java/org/redisson/client/handler/CommandDecoder.java +++ b/redisson/src/main/java/org/redisson/client/handler/CommandDecoder.java @@ -205,7 +205,7 @@ public class CommandDecoder extends ReplayingDecoder { decode(in, cmd, null, channel, false, null); sendNext(channel, data); } catch (Exception e) { - log.error("Unable to decode data. channel: " + channel + ", reply: " + LogHelper.toString(in) + ", command: " + LogHelper.toString(data), e); + log.error("Unable to decode data. channel: {}, reply: {}, command: {}", channel, LogHelper.toString(in), LogHelper.toString(data), e); in.readerIndex(endIndex); sendNext(channel); cmd.tryFailure(e); @@ -228,7 +228,7 @@ public class CommandDecoder extends ReplayingDecoder { } sendNext(channel); } catch (Exception e) { - log.error("Unable to decode data. channel: " + channel + ", reply: " + LogHelper.toString(in), e); + log.error("Unable to decode data. channel: {}, reply: {}", channel, LogHelper.toString(in), e); sendNext(channel); throw e; } diff --git a/redisson/src/main/java/org/redisson/client/handler/CommandPubSubDecoder.java b/redisson/src/main/java/org/redisson/client/handler/CommandPubSubDecoder.java index 79b0cb94c..c38676282 100644 --- a/redisson/src/main/java/org/redisson/client/handler/CommandPubSubDecoder.java +++ b/redisson/src/main/java/org/redisson/client/handler/CommandPubSubDecoder.java @@ -87,7 +87,7 @@ public class CommandPubSubDecoder extends CommandDecoder { } sendNext(channel); } catch (Exception e) { - log.error("Unable to decode data. channel: " + channel + ", reply: " + LogHelper.toString(in), e); + log.error("Unable to decode data. channel: {}, reply: {}", channel, LogHelper.toString(in), e); sendNext(channel); throw e; } @@ -99,7 +99,7 @@ public class CommandPubSubDecoder extends CommandDecoder { } sendNext(channel, data); } catch (Exception e) { - log.error("Unable to decode data. channel: " + channel + ", reply: " + LogHelper.toString(in), e); + log.error("Unable to decode data. channel: {}, reply: {}", channel, LogHelper.toString(in), e); cmd.tryFailure(e); sendNext(channel); throw e; diff --git a/redisson/src/main/java/org/redisson/client/handler/ErrorsLoggingHandler.java b/redisson/src/main/java/org/redisson/client/handler/ErrorsLoggingHandler.java index c3fa98156..bfcb2a36f 100644 --- a/redisson/src/main/java/org/redisson/client/handler/ErrorsLoggingHandler.java +++ b/redisson/src/main/java/org/redisson/client/handler/ErrorsLoggingHandler.java @@ -44,7 +44,7 @@ public class ErrorsLoggingHandler extends ChannelDuplexHandler { } } - log.error("Exception occured. Channel: " + ctx.channel(), cause); + log.error("Exception occured. Channel: {}", ctx.channel(), cause); } } diff --git a/redisson/src/main/java/org/redisson/client/handler/PingConnectionHandler.java b/redisson/src/main/java/org/redisson/client/handler/PingConnectionHandler.java index f622596ef..0a849b3fa 100644 --- a/redisson/src/main/java/org/redisson/client/handler/PingConnectionHandler.java +++ b/redisson/src/main/java/org/redisson/client/handler/PingConnectionHandler.java @@ -89,7 +89,7 @@ public class PingConnectionHandler extends ChannelInboundHandlerAdapter { || cause instanceof RedisClusterDownException || cause instanceof RedisBusyException)) { if (!future.isCancelled()) { - log.error("Unable to send PING command over channel: " + ctx.channel(), cause); + log.error("Unable to send PING command over channel: {}", ctx.channel(), cause); } log.debug("channel: {} closed due to PING response timeout set in {} ms", ctx.channel(), config.getPingConnectionInterval()); diff --git a/redisson/src/main/java/org/redisson/cluster/ClusterConnectionManager.java b/redisson/src/main/java/org/redisson/cluster/ClusterConnectionManager.java index 18212b7ab..8d93eba09 100644 --- a/redisson/src/main/java/org/redisson/cluster/ClusterConnectionManager.java +++ b/redisson/src/main/java/org/redisson/cluster/ClusterConnectionManager.java @@ -315,7 +315,7 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager { CompletableFuture f = entry.setupMasterEntry(new RedisURI(config.getMasterAddress()), configEndpointHostName); f.whenComplete((masterClient, ex3) -> { if (ex3 != null) { - log.error("Can't add master: " + partition.getMasterAddress() + " for slot ranges: " + partition.getSlotRanges(), ex3); + log.error("Can't add master: {} for slot ranges: {}", partition.getMasterAddress(), partition.getSlotRanges(), ex3); result.completeExceptionally(ex3); return; } @@ -329,8 +329,7 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager { CompletableFuture fs = entry.initSlaveBalancer(partition.getFailedSlaveAddresses(), configEndpointHostName); fs.whenComplete((r, ex) -> { if (ex != null) { - log.error("unable to add slave for: " + partition.getMasterAddress() - + " slot ranges: " + partition.getSlotRanges(), ex); + log.error("unable to add slave for: {} slot ranges: {}", partition.getMasterAddress(), partition.getSlotRanges(), ex); result.completeExceptionally(ex); return; } @@ -449,7 +448,7 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager { RFuture> future = connection.async(clusterNodesCommand); future.whenComplete((nodes, e) -> { if (e != null) { - log.error("Unable to execute " + clusterNodesCommand, e); + log.error("Unable to execute {}", clusterNodesCommand, e); lastException.set(e); getShutdownLatch().release(); checkClusterState(cfg, iterator, lastException); @@ -481,7 +480,7 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager { for (ClusterNodeInfo clusterNodeInfo : nodes) { nodesValue.append(clusterNodeInfo.getNodeInfo()).append("\n"); } - log.error("Unable to parse cluster nodes state got from: " + connection.getRedisClient().getAddr() + ":\n" + nodesValue, ex); + log.error("Unable to parse cluster nodes state got from: {}:\n{}", connection.getRedisClient().getAddr(), nodesValue, ex); lastException.set(ex); getShutdownLatch().release(); checkClusterState(cfg, iterator, lastException); @@ -602,7 +601,7 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager { CompletableFuture slaveUpFuture = entry.addSlave(uri, false, NodeType.SLAVE, configEndpointHostName); slaveUpFuture = slaveUpFuture.whenComplete((res, ex) -> { if (ex != null) { - log.error("Can't add slave: " + uri, ex); + log.error("Can't add slave: {}", uri, ex); } }).thenCompose(res -> { currentPart.addSlaveAddress(uri); diff --git a/redisson/src/main/java/org/redisson/command/CommandBatchService.java b/redisson/src/main/java/org/redisson/command/CommandBatchService.java index 8dd182f40..289cac79f 100644 --- a/redisson/src/main/java/org/redisson/command/CommandBatchService.java +++ b/redisson/src/main/java/org/redisson/command/CommandBatchService.java @@ -312,7 +312,7 @@ public class CommandBatchService extends CommandAsyncService { entryResult = objectBuilder.tryHandleReference(entryResult, referenceType); } } catch (ReflectiveOperationException exc) { - log.error("Unable to handle reference from " + entryResult, exc); + log.error("Unable to handle reference from {}", entryResult, exc); } responses.add(entryResult); } diff --git a/redisson/src/main/java/org/redisson/connection/DNSMonitor.java b/redisson/src/main/java/org/redisson/connection/DNSMonitor.java index 7a54c459c..026c25bac 100644 --- a/redisson/src/main/java/org/redisson/connection/DNSMonitor.java +++ b/redisson/src/main/java/org/redisson/connection/DNSMonitor.java @@ -99,7 +99,7 @@ public class DNSMonitor { Future resolveFuture = resolver.resolve(InetSocketAddress.createUnresolved(entry.getKey().getHost(), entry.getKey().getPort())); resolveFuture.addListener((FutureListener) future -> { if (!future.isSuccess()) { - log.error("Unable to resolve " + entry.getKey().getHost(), future.cause()); + log.error("Unable to resolve {}", entry.getKey().getHost(), future.cause()); promise.complete(null); return; } @@ -146,7 +146,7 @@ public class DNSMonitor { Future resolveFuture = resolver.resolve(InetSocketAddress.createUnresolved(entry.getKey().getHost(), entry.getKey().getPort())); resolveFuture.addListener((FutureListener) future -> { if (!future.isSuccess()) { - log.error("Unable to resolve " + entry.getKey().getHost(), future.cause()); + log.error("Unable to resolve {}", entry.getKey().getHost(), future.cause()); promise.complete(null); return; } @@ -182,7 +182,7 @@ public class DNSMonitor { CompletableFuture addFuture = masterSlaveEntry.addSlave(newSlaveAddr, entry.getKey()); addFuture.whenComplete((res, e) -> { if (e != null) { - log.error("Can't add slave: " + newSlaveAddr, e); + log.error("Can't add slave: {}", newSlaveAddr, e); promise.complete(null); return; } diff --git a/redisson/src/main/java/org/redisson/connection/MasterSlaveConnectionManager.java b/redisson/src/main/java/org/redisson/connection/MasterSlaveConnectionManager.java index 903d86caa..1a3e0ebd6 100644 --- a/redisson/src/main/java/org/redisson/connection/MasterSlaveConnectionManager.java +++ b/redisson/src/main/java/org/redisson/connection/MasterSlaveConnectionManager.java @@ -572,7 +572,7 @@ public class MasterSlaveConnectionManager implements ConnectionManager { public void releaseWrite(NodeSource source, RedisConnection connection) { MasterSlaveEntry entry = getEntry(source); if (entry == null) { - log.error("Node: " + source + " can't be found"); + log.error("Node: {} can't be found", source); } else { entry.releaseWrite(connection); } @@ -582,7 +582,7 @@ public class MasterSlaveConnectionManager implements ConnectionManager { public void releaseRead(NodeSource source, RedisConnection connection) { MasterSlaveEntry entry = getEntry(source); if (entry == null) { - log.error("Node: " + source + " can't be found"); + log.error("Node: {} can't be found", source); } else { entry.releaseRead(connection); } @@ -720,7 +720,7 @@ public class MasterSlaveConnectionManager implements ConnectionManager { Future future = resolver.resolve(addr); future.addListener((FutureListener) f -> { if (!f.isSuccess()) { - log.error("Unable to resolve " + address, f.cause()); + log.error("Unable to resolve {}", address, f.cause()); result.completeExceptionally(f.cause()); return; } diff --git a/redisson/src/main/java/org/redisson/connection/MasterSlaveEntry.java b/redisson/src/main/java/org/redisson/connection/MasterSlaveEntry.java index f1fb125ab..831cc8c60 100644 --- a/redisson/src/main/java/org/redisson/connection/MasterSlaveEntry.java +++ b/redisson/src/main/java/org/redisson/connection/MasterSlaveEntry.java @@ -525,7 +525,7 @@ public class MasterSlaveEntry { masterEntry.shutdownAsync(); masterEntry = oldMaster; } - log.error("Unable to change master from: " + oldMaster.getClient().getAddr() + " to: " + address, e); + log.error("Unable to change master from: {} to: {}", oldMaster.getClient().getAddr(), address, e); return; } diff --git a/redisson/src/main/java/org/redisson/connection/ReplicatedConnectionManager.java b/redisson/src/main/java/org/redisson/connection/ReplicatedConnectionManager.java index 501fa1f4a..698e4adff 100644 --- a/redisson/src/main/java/org/redisson/connection/ReplicatedConnectionManager.java +++ b/redisson/src/main/java/org/redisson/connection/ReplicatedConnectionManager.java @@ -98,7 +98,7 @@ public class ReplicatedConnectionManager extends MasterSlaveConnectionManager { throw new RedisConnectionException("Can't connect to servers!"); } if (this.config.getReadMode() != ReadMode.MASTER && this.config.getSlaveAddresses().isEmpty()) { - log.warn("ReadMode = " + this.config.getReadMode() + ", but slave nodes are not found! Please specify all nodes in replicated mode."); + log.warn("ReadMode = {}, but slave nodes are not found! Please specify all nodes in replicated mode.", this.config.getReadMode()); } initSingleEntry(); @@ -172,8 +172,7 @@ public class ReplicatedConnectionManager extends MasterSlaveConnectionManager { RedisConnection connection = connectionFuture.toCompletableFuture().join(); if (!ip.equals(connection.getRedisClient().getAddr())) { disconnectNode(uri); - log.info("Hostname: " + uri + " has changed IP from: " - + connection.getRedisClient().getAddr() + " to " + ip); + log.info("Hostname: {} has changed IP from: {} to {}", uri, connection.getRedisClient().getAddr(), ip); return CompletableFuture.>completedFuture(null); } @@ -194,7 +193,7 @@ public class ReplicatedConnectionManager extends MasterSlaveConnectionManager { } else if (currentMaster.compareAndSet(master, addr)) { CompletableFuture changeFuture = changeMaster(singleSlotRange.getStartSlot(), uri); return changeFuture.exceptionally(e -> { - log.error("Unable to change master to " + addr, e); + log.error("Unable to change master to {}", addr, e); currentMaster.compareAndSet(addr, master); return null; }); diff --git a/redisson/src/main/java/org/redisson/connection/SentinelConnectionManager.java b/redisson/src/main/java/org/redisson/connection/SentinelConnectionManager.java index 1d22e1739..e68cd4d7a 100755 --- a/redisson/src/main/java/org/redisson/connection/SentinelConnectionManager.java +++ b/redisson/src/main/java/org/redisson/connection/SentinelConnectionManager.java @@ -203,7 +203,7 @@ public class SentinelConnectionManager extends MasterSlaveConnectionManager { throw new RedisConnectionException("Can't connect to servers!", lastException); } if (this.config.getReadMode() != ReadMode.MASTER && this.config.getSlaveAddresses().isEmpty()) { - log.warn("ReadMode = " + this.config.getReadMode() + ", but slave nodes are not found!"); + log.warn("ReadMode = {}, but slave nodes are not found!", this.config.getReadMode()); } initSingleEntry(); @@ -291,7 +291,7 @@ public class SentinelConnectionManager extends MasterSlaveConnectionManager { Future> allNodes = sentinelResolver.resolveAll(InetSocketAddress.createUnresolved(host.getHost(), host.getPort())); allNodes.addListener((FutureListener>) future -> { if (!future.isSuccess()) { - log.error("Unable to resolve " + host.getHost(), future.cause()); + log.error("Unable to resolve {}", host.getHost(), future.cause()); return; } @@ -369,7 +369,7 @@ public class SentinelConnectionManager extends MasterSlaveConnectionManager { CompletableFuture future = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); future.whenComplete((r, e) -> { if (e != null) { - log.error("Can't execute SENTINEL commands on " + connection.getRedisClient().getAddr(), e); + log.error("Can't execute SENTINEL commands on {}", connection.getRedisClient().getAddr(), e); } getShutdownLatch().release(); @@ -460,7 +460,7 @@ public class SentinelConnectionManager extends MasterSlaveConnectionManager { futures.add(resolvedFuture .whenComplete((r, exc) -> { if (exc != null) { - log.error("Unable to resolve addresses " + host + " and/or " + masterHost, exc); + log.error("Unable to resolve addresses {} and/or {}", host, masterHost, exc); } }) .thenCompose(res -> { @@ -477,7 +477,7 @@ public class SentinelConnectionManager extends MasterSlaveConnectionManager { currentSlaves.add(slaveAddr); return addSlave(slaveAddr).whenComplete((r, e) -> { if (e != null) { - log.error("Unable to add slave " + slaveAddr, e); + log.error("Unable to add slave {}", slaveAddr, e); } }); })); diff --git a/redisson/src/main/java/org/redisson/connection/balancer/LoadBalancerManager.java b/redisson/src/main/java/org/redisson/connection/balancer/LoadBalancerManager.java index ee0d6acfb..bc9ac48ff 100644 --- a/redisson/src/main/java/org/redisson/connection/balancer/LoadBalancerManager.java +++ b/redisson/src/main/java/org/redisson/connection/balancer/LoadBalancerManager.java @@ -160,7 +160,7 @@ public class LoadBalancerManager { CompletableFuture future = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); future.whenComplete((r, e) -> { if (e != null) { - log.error("Unable to unfreeze entry: " + entry, e); + log.error("Unable to unfreeze entry: {}", entry, e); entry.setInitialized(false); connectionManager.newTimeout(t -> { unfreeze(entry, freezeReason); @@ -197,7 +197,7 @@ public class LoadBalancerManager { CompletableFuture future = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); return future.whenComplete((r, e) -> { if (e != null) { - log.error("Unable to unfreeze entry: " + entry, e); + log.error("Unable to unfreeze entry: {}", entry, e); entry.setInitialized(false); return; } diff --git a/redisson/src/main/java/org/redisson/connection/pool/ConnectionPool.java b/redisson/src/main/java/org/redisson/connection/pool/ConnectionPool.java index b20b8d463..ab1606578 100644 --- a/redisson/src/main/java/org/redisson/connection/pool/ConnectionPool.java +++ b/redisson/src/main/java/org/redisson/connection/pool/ConnectionPool.java @@ -341,8 +341,8 @@ abstract class ConnectionPool { private void checkForReconnect(ClientConnectionsEntry entry, Throwable cause) { masterSlaveEntry.slaveDownAsync(entry, FreezeReason.RECONNECT).thenAccept(r -> { if (r) { - log.error("slave " + entry.getClient().getAddr() + " has been disconnected after " - + config.getFailedSlaveCheckInterval() + " ms interval since moment of the first failed connection", cause); + log.error("slave {} has been disconnected after {} ms interval since moment of the first failed connection", + entry.getClient().getAddr(), config.getFailedSlaveCheckInterval(), cause); scheduleCheck(entry); } }); diff --git a/redisson/src/main/java/org/redisson/eviction/EvictionTask.java b/redisson/src/main/java/org/redisson/eviction/EvictionTask.java index c49e76812..2bc45416a 100644 --- a/redisson/src/main/java/org/redisson/eviction/EvictionTask.java +++ b/redisson/src/main/java/org/redisson/eviction/EvictionTask.java @@ -74,7 +74,7 @@ abstract class EvictionTask implements Runnable { RFuture future = execute(); future.whenComplete((size, e) -> { if (e != null) { - log.error("Unable to evict elements for '" + getName() + "'", e); + log.error("Unable to evict elements for '{}'", getName(), e); schedule(); return; } diff --git a/redisson/src/main/java/org/redisson/executor/RedissonExecutorRemoteService.java b/redisson/src/main/java/org/redisson/executor/RedissonExecutorRemoteService.java index 5d0b33c08..ca3190bdb 100644 --- a/redisson/src/main/java/org/redisson/executor/RedissonExecutorRemoteService.java +++ b/redisson/src/main/java/org/redisson/executor/RedissonExecutorRemoteService.java @@ -118,7 +118,7 @@ public class RedissonExecutorRemoteService extends RedissonRemoteService { } RemoteServiceResponse response = new RemoteServiceResponse(request.getId(), e.getCause()); responsePromise.complete(response); - log.error("Can't execute: " + request, e); + log.error("Can't execute: {}", request, e); } if (cancelRequestFuture != null) { diff --git a/redisson/src/main/java/org/redisson/remote/BaseRemoteProxy.java b/redisson/src/main/java/org/redisson/remote/BaseRemoteProxy.java index 99e9de3bb..5ed078b2e 100644 --- a/redisson/src/main/java/org/redisson/remote/BaseRemoteProxy.java +++ b/redisson/src/main/java/org/redisson/remote/BaseRemoteProxy.java @@ -192,7 +192,7 @@ public abstract class BaseRemoteProxy { return; } - log.error("Can't get response from " + responseQueueName, e); + log.error("Can't get response from {}", responseQueueName, e); return; } diff --git a/redisson/src/test/java/org/redisson/RedissonFairLockTest.java b/redisson/src/test/java/org/redisson/RedissonFairLockTest.java index bf5ade9dd..1ef2ab0f4 100644 --- a/redisson/src/test/java/org/redisson/RedissonFairLockTest.java +++ b/redisson/src/test/java/org/redisson/RedissonFairLockTest.java @@ -76,21 +76,21 @@ public class RedissonFairLockTest extends BaseConcurrentTest { for (int i = 0; i < 50; i++) { final int finalI = i; executor.submit(() -> { - log.info("running " + finalI + " in thread " + Thread.currentThread().getId()); + log.info("running {} in thread {}", finalI, Thread.currentThread().getId()); try { if (lock.tryLock(500, leaseTimeSeconds * 1000, TimeUnit.MILLISECONDS)) { - log.info("Lock taken by thread " + Thread.currentThread().getId()); + log.info("Lock taken by thread {}", Thread.currentThread().getId()); Thread.sleep(10000); try { //this could fail before use sleep for the same value as the lock expiry, that's fine //for the purpose of this test lock.unlock(); - log.info("Lock released by thread " + Thread.currentThread().getId()); + log.info("Lock released by thread {}", Thread.currentThread().getId()); } catch (Exception ignored) { } } } catch (InterruptedException ex) { - log.warn("Interrupted " + Thread.currentThread().getId()); + log.warn("Interrupted {}", Thread.currentThread().getId()); } catch (Exception ex) { log.error(ex.getMessage(), ex); } @@ -104,17 +104,17 @@ public class RedissonFairLockTest extends BaseConcurrentTest { //we now launch one more thread and kill it before it manages to fail and clean up //that thread will end up with a timeout that will prevent any others from taking the lock for a long time executor.submit(() -> { - log.info("Final thread trying to take the lock with thread id: " + Thread.currentThread().getId()); + log.info("Final thread trying to take the lock with thread id: {}", Thread.currentThread().getId()); try { lastThreadTryingToLock.set(true); if (lock.tryLock(30000, 30000, TimeUnit.MILLISECONDS)) { - log.info("Lock taken by final thread " + Thread.currentThread().getId()); + log.info("Lock taken by final thread {}", Thread.currentThread().getId()); Thread.sleep(1000); lock.unlock(); - log.info("Lock released by final thread " + Thread.currentThread().getId()); + log.info("Lock released by final thread {}", Thread.currentThread().getId()); } } catch (InterruptedException ex) { - log.warn("Interrupted " + Thread.currentThread().getId()); + log.warn("Interrupted {}", Thread.currentThread().getId()); } catch (Exception ex) { log.error(ex.getMessage(), ex); } @@ -148,7 +148,7 @@ public class RedissonFairLockTest extends BaseConcurrentTest { int i = 0; for (Long timeout : queue) { long epiry = ((timeout - new Date().getTime()) / 1000); - log.info("Item " + (i++) + " expires in " + epiry + " seconds"); + log.info("Item {} expires in {} seconds", i++, epiry); //the Redisson library uses this 60000*5ms delay in the code if (epiry > leaseTimeSeconds + 60*5) { Assertions.fail("It would take more than " + leaseTimeSeconds + "s to get the lock!"); @@ -168,21 +168,21 @@ public class RedissonFairLockTest extends BaseConcurrentTest { for (int i = 0; i < 3; i++) { final int finalI = i; executor.submit(() -> { - log.info("running " + finalI + " in thread " + Thread.currentThread().getId()); + log.info("running {} in thread {}", finalI, Thread.currentThread().getId()); try { if (lock.tryLock(3000, leaseTimeSeconds * 1000, TimeUnit.MILLISECONDS)) { - log.info("Lock taken by thread " + Thread.currentThread().getId()); + log.info("Lock taken by thread {}", Thread.currentThread().getId()); Thread.sleep(100); try { //this could fail before use sleep for the same value as the lock expiry, that's fine //for the purpose of this test lock.unlock(); - log.info("Lock released by thread " + Thread.currentThread().getId()); + log.info("Lock released by thread {}", Thread.currentThread().getId()); } catch (Exception ignored) { } } } catch (InterruptedException ex) { - log.warn("Interrupted " + Thread.currentThread().getId()); + log.warn("Interrupted {}", Thread.currentThread().getId()); } catch (Exception ex) { log.error(ex.getMessage(), ex); } @@ -196,14 +196,14 @@ public class RedissonFairLockTest extends BaseConcurrentTest { //we now launch one more thread and kill it before it manages to fail and clean up //that thread will end up with a timeout that will prevent any others from taking the lock for a long time executor.submit(() -> { - log.info("Final thread trying to take the lock with thread id: " + Thread.currentThread().getId()); + log.info("Final thread trying to take the lock with thread id: {}", Thread.currentThread().getId()); try { lastThreadTryingToLock.set(true); if (lock.tryLock(30000, 30000, TimeUnit.MILLISECONDS)) { - log.info("Lock taken by final thread " + Thread.currentThread().getId()); + log.info("Lock taken by final thread {}", Thread.currentThread().getId()); Thread.sleep(1000); lock.unlock(); - log.info("Lock released by final thread " + Thread.currentThread().getId()); + log.info("Lock released by final thread {}", Thread.currentThread().getId()); } } catch (InterruptedException ex) { log.warn("Interrupted"); @@ -240,7 +240,7 @@ public class RedissonFairLockTest extends BaseConcurrentTest { int i = 0; for (Long timeout : queue) { long epiry = ((timeout - new Date().getTime()) / 1000); - log.info("Item " + (i++) + " expires in " + epiry + " seconds"); + log.info("Item {} expires in {} seconds", i++, epiry); //the Redisson library uses this 5000ms delay in the code if (epiry > leaseTimeSeconds + 60*5) { Assertions.fail("It would take more than " + leaseTimeSeconds + "s to get the lock!"); @@ -499,21 +499,21 @@ public class RedissonFairLockTest extends BaseConcurrentTest { for (int i = 0; i < 10; i++) { final int finalI = i; executor.submit(() -> { - log.info("running " + finalI + " in thread " + Thread.currentThread().getId()); + log.info("running {} in thread {}", finalI, Thread.currentThread().getId()); try { if (lock.tryLock(3000, leaseTimeSeconds * 1000, TimeUnit.MILLISECONDS)) { - log.info("Lock taken by thread " + Thread.currentThread().getId()); + log.info("Lock taken by thread {}", Thread.currentThread().getId()); Thread.sleep(100); try { //this could fail before use sleep for the same value as the lock expiry, that's fine //for the purpose of this test lock.unlock(); - log.info("Lock released by thread " + Thread.currentThread().getId()); + log.info("Lock released by thread {}", Thread.currentThread().getId()); } catch (Exception ignored) { } } } catch (InterruptedException ex) { - log.warn("Interrupted " + Thread.currentThread().getId()); + log.warn("Interrupted {}", Thread.currentThread().getId()); } catch (Exception ex) { log.error(ex.getMessage(), ex); } @@ -527,17 +527,17 @@ public class RedissonFairLockTest extends BaseConcurrentTest { //we now launch one more thread and kill it before it manages to fail and clean up //that thread will end up with a timeout that will prevent any others from taking the lock for a long time executor.submit(() -> { - log.info("Final thread trying to take the lock with thread id: " + Thread.currentThread().getId()); + log.info("Final thread trying to take the lock with thread id: {}", Thread.currentThread().getId()); try { lastThreadTryingToLock.set(true); if (lock.tryLock(30000, 30000, TimeUnit.MILLISECONDS)) { - log.info("Lock taken by final thread " + Thread.currentThread().getId()); + log.info("Lock taken by final thread {}", Thread.currentThread().getId()); Thread.sleep(1000); lock.unlock(); - log.info("Lock released by final thread " + Thread.currentThread().getId()); + log.info("Lock released by final thread {}", Thread.currentThread().getId()); } } catch (InterruptedException ex) { - log.warn("Interrupted " + Thread.currentThread().getId()); + log.warn("Interrupted {}", Thread.currentThread().getId()); } catch (Exception ex) { log.error(ex.getMessage(), ex); } @@ -571,7 +571,7 @@ public class RedissonFairLockTest extends BaseConcurrentTest { for (int i = 0; i < queue.size(); i++) { long timeout = queue.get(i); long epiry = ((timeout - new Date().getTime()) / 1000); - log.info("Item " + i + " expires in " + epiry + " seconds"); + log.info("Item {} expires in {} seconds", i, epiry); // the Redisson library uses this 60000*5ms delay in the code Assertions.assertFalse(epiry > leaseTimeSeconds + 60*5 * (i + 1), "It would take more than " + (leaseTimeSeconds + 60*5 * (i + 1)) + "s to get the lock!"); From daccfae3bf165b53ac0f920e32747f1ece5898c1 Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Mon, 12 Dec 2022 18:59:03 +0300 Subject: [PATCH 18/58] tests fixed --- redisson/src/test/java/org/redisson/RedissonTopicTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/redisson/src/test/java/org/redisson/RedissonTopicTest.java b/redisson/src/test/java/org/redisson/RedissonTopicTest.java index 55d1b849e..233c2dc05 100644 --- a/redisson/src/test/java/org/redisson/RedissonTopicTest.java +++ b/redisson/src/test/java/org/redisson/RedissonTopicTest.java @@ -290,6 +290,7 @@ public class RedissonTopicTest { await().atMost(Duration.ofSeconds(1)).untilTrue(stringMessageReceived); await().atMost(Duration.ofSeconds(1)).untilTrue(longMessageReceived); + redisson.shutdown(); } @Test @@ -366,6 +367,7 @@ public class RedissonTopicTest { topic1.removeListener(listenerId2); assertThat(l.await(5, TimeUnit.SECONDS)).isTrue(); + redisson.shutdown(); } @Test From 8e24ca4161717d6e45bac203be4c792b4031996b Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Tue, 13 Dec 2022 09:49:07 +0300 Subject: [PATCH 19/58] Feature - entries-read and lag fields added to StreamGroup object. #4735 --- .../java/org/redisson/api/StreamGroup.java | 29 +++++++++++++++++-- .../decoder/StreamGroupInfoDecoder.java | 17 +++++++++-- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/redisson/src/main/java/org/redisson/api/StreamGroup.java b/redisson/src/main/java/org/redisson/api/StreamGroup.java index b2a72b558..0b59a3888 100644 --- a/redisson/src/main/java/org/redisson/api/StreamGroup.java +++ b/redisson/src/main/java/org/redisson/api/StreamGroup.java @@ -27,14 +27,22 @@ public class StreamGroup { private final int consumers; private final int pending; private final StreamMessageId lastDeliveredId; + private final int entriesRead; + private final int lag; public StreamGroup(String name, int consumers, int pending, StreamMessageId lastDeliveredId) { + this(name, consumers, pending, lastDeliveredId, 0, 0); + } + + public StreamGroup(String name, int consumers, int pending, StreamMessageId lastDeliveredId, int entriesRead, int lag) { this.name = name; this.consumers = consumers; this.pending = pending; this.lastDeliveredId = lastDeliveredId; + this.entriesRead = entriesRead; + this.lag = lag; } - + /** * Returns last delivered StreamMessageId for this group * @@ -70,5 +78,22 @@ public class StreamGroup { public int getPending() { return pending; } - + + /** + * Returns amount of entries that the group had read + * + * @return amount of read entries + */ + public int getEntriesRead() { + return entriesRead; + } + + /** + * Returns amount of entries that are still waiting for delivery + * + * @return amount of entries for delivery + */ + public int getLag() { + return lag; + } } diff --git a/redisson/src/main/java/org/redisson/client/protocol/decoder/StreamGroupInfoDecoder.java b/redisson/src/main/java/org/redisson/client/protocol/decoder/StreamGroupInfoDecoder.java index ef25f5773..cc6832e5d 100644 --- a/redisson/src/main/java/org/redisson/client/protocol/decoder/StreamGroupInfoDecoder.java +++ b/redisson/src/main/java/org/redisson/client/protocol/decoder/StreamGroupInfoDecoder.java @@ -20,6 +20,7 @@ import org.redisson.client.handler.State; import org.redisson.client.protocol.convertor.StreamIdConvertor; import java.util.List; +import java.util.Optional; /** * @@ -30,9 +31,19 @@ public class StreamGroupInfoDecoder implements MultiDecoder { @Override public StreamGroup decode(List parts, State state) { - return new StreamGroup((String) parts.get(1), - ((Long) parts.get(3)).intValue(), ((Long) parts.get(5)).intValue(), - StreamIdConvertor.INSTANCE.convert(parts.get(7))); + if (parts.size() == 8) { + return new StreamGroup((String) parts.get(1), + ((Long) parts.get(3)).intValue(), + ((Long) parts.get(5)).intValue(), + StreamIdConvertor.INSTANCE.convert(parts.get(7))); + } + + return new StreamGroup((String) parts.get(1), + ((Long) parts.get(3)).intValue(), + ((Long) parts.get(5)).intValue(), + StreamIdConvertor.INSTANCE.convert(parts.get(7)), + Optional.ofNullable((Long) parts.get(9)).orElse(0L).intValue(), + Optional.ofNullable((Long) parts.get(11)).orElse(0L).intValue()); } } From c6b2e5b7222024103aaef7d2a5fb5d8d3deb709a Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Tue, 13 Dec 2022 13:06:55 +0300 Subject: [PATCH 20/58] Fixed - PubSub connection isn't reused if it reached subscriptions limit before unsubscribe operation. PubSub connection returns to connection pool only if subscriptions limit was reached. #4738 --- .../pubsub/PubSubConnectionEntry.java | 12 ++- .../pubsub/PublishSubscribeService.java | 100 ++++++++++-------- 2 files changed, 63 insertions(+), 49 deletions(-) diff --git a/redisson/src/main/java/org/redisson/pubsub/PubSubConnectionEntry.java b/redisson/src/main/java/org/redisson/pubsub/PubSubConnectionEntry.java index 9b088d3a5..be2bcfac8 100644 --- a/redisson/src/main/java/org/redisson/pubsub/PubSubConnectionEntry.java +++ b/redisson/src/main/java/org/redisson/pubsub/PubSubConnectionEntry.java @@ -156,6 +156,10 @@ public class PubSubConnectionEntry { return subscribedChannelsAmount.incrementAndGet(); } + public boolean isFree() { + return subscribedChannelsAmount.get() == connectionManager.getConfig().getSubscriptionsPerConnection(); + } + public void subscribe(Codec codec, PubSubType type, ChannelName channelName, CompletableFuture subscribeFuture) { ChannelFuture future; if (PubSubType.SUBSCRIBE == type) { @@ -249,7 +253,11 @@ public class PubSubConnectionEntry { @Override public String toString() { - return "PubSubConnectionEntry [subscribedChannelsAmount=" + subscribedChannelsAmount + ", conn=" + conn + "]"; + return "PubSubConnectionEntry{" + + "subscribedChannelsAmount=" + subscribedChannelsAmount + + ", conn=" + conn + + ", subscribeChannelListeners=" + subscribeChannelListeners + + ", channelListeners=" + channelListeners + + '}'; } - } diff --git a/redisson/src/main/java/org/redisson/pubsub/PublishSubscribeService.java b/redisson/src/main/java/org/redisson/pubsub/PublishSubscribeService.java index f78e38a23..c76b6b743 100644 --- a/redisson/src/main/java/org/redisson/pubsub/PublishSubscribeService.java +++ b/redisson/src/main/java/org/redisson/pubsub/PublishSubscribeService.java @@ -450,22 +450,19 @@ public class PublishSubscribeService { return CompletableFuture.completedFuture(null); } + MasterSlaveEntry msEntry = getEntry(channelName); CompletableFuture result = new CompletableFuture<>(); BaseRedisPubSubListener listener = new BaseRedisPubSubListener() { @Override public boolean onStatus(PubSubType type, CharSequence channel) { if (type == topicType && channel.equals(channelName)) { - if (entry.release() == 1) { - MasterSlaveEntry msEntry = getEntry(channelName); - if (msEntry != null) { - msEntry.returnPubSubConnection(entry.getConnection()); - } else { - entry.getConnection().closeAsync(); - } - } + freePubSubLock.acquire().thenAccept(c -> { + release(entry, msEntry); + freePubSubLock.release(); - result.complete(null); + result.complete(null); + }); return true; } return false; @@ -477,6 +474,29 @@ public class PublishSubscribeService { return result; } + private void release(PubSubConnectionEntry entry, MasterSlaveEntry msEntry) { + entry.release(); + if (entry.isFree()) { + if (msEntry != null) { + PubSubEntry ee = entry2PubSubConnection.get(msEntry); + if (ee != null) { + ee.getEntries().remove(entry); + } + msEntry.returnPubSubConnection(entry.getConnection()); + } else { + entry.getConnection().closeAsync(); + } + return; + } + + if (msEntry != null) { + PubSubEntry ee = entry2PubSubConnection.computeIfAbsent(msEntry, e -> new PubSubEntry()); + if (!ee.getEntries().contains(entry)) { + ee.getEntries().add(entry); + } + } + } + public void remove(MasterSlaveEntry entry) { entry2PubSubConnection.remove(entry); } @@ -507,40 +527,37 @@ public class PublishSubscribeService { return CompletableFuture.completedFuture(null); } - CompletableFuture psf = freePubSubLock.acquire(); - return psf.thenCompose(r -> { - PubSubEntry ee = entry2PubSubConnection.getOrDefault(e, new PubSubEntry()); - Queue freePubSubConnections = ee.getEntries(); - freePubSubConnections.remove(entry); - freePubSubLock.release(); + Codec entryCodec; + if (topicType == PubSubType.PUNSUBSCRIBE) { + entryCodec = entry.getConnection().getPatternChannels().get(channelName); + } else if (topicType == PubSubType.SUNSUBSCRIBE) { + entryCodec = entry.getConnection().getShardedChannels().get(channelName); + } else { + entryCodec = entry.getConnection().getChannels().get(channelName); + } - Codec entryCodec; - if (topicType == PubSubType.PUNSUBSCRIBE) { - entryCodec = entry.getConnection().getPatternChannels().get(channelName); - } else if (topicType == PubSubType.SUNSUBSCRIBE) { - entryCodec = entry.getConnection().getShardedChannels().get(channelName); - } else { - entryCodec = entry.getConnection().getChannels().get(channelName); - } + CompletableFuture result = new CompletableFuture<>(); + RedisPubSubListener listener = new BaseRedisPubSubListener() { - CompletableFuture result = new CompletableFuture<>(); - RedisPubSubListener listener = new BaseRedisPubSubListener() { + @Override + public boolean onStatus(PubSubType type, CharSequence channel) { + if (type == topicType && channel.equals(channelName)) { + lock.release(); + freePubSubLock.acquire().thenAccept(c -> { + release(entry, e); + freePubSubLock.release(); - @Override - public boolean onStatus(PubSubType type, CharSequence channel) { - if (type == topicType && channel.equals(channelName)) { - lock.release(); result.complete(entryCodec); - return true; - } - return false; + }); + return true; } + return false; + } - }; + }; - entry.unsubscribe(topicType, channelName, listener); - return result; - }); + entry.unsubscribe(topicType, channelName, listener); + return result; }); } @@ -580,17 +597,6 @@ public class PublishSubscribeService { return; } - freePubSubLock.acquire().thenAccept(r -> { - try { - PubSubEntry ee = entry2PubSubConnection.get(en); - if (ee != null) { - ee.getEntries().removeIf(e -> e.getConnection().equals(redisPubSubConnection)); - } - } finally { - freePubSubLock.release(); - } - }); - reattachPubSubListeners(redisPubSubConnection.getChannels().keySet(), en, PubSubType.UNSUBSCRIBE); reattachPubSubListeners(redisPubSubConnection.getShardedChannels().keySet(), en, PubSubType.SUNSUBSCRIBE); reattachPubSubListeners(redisPubSubConnection.getPatternChannels().keySet(), en, PubSubType.PUNSUBSCRIBE); From 8f286dbe73e705a51fa4fe302cf044c793809362 Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Tue, 13 Dec 2022 14:24:51 +0300 Subject: [PATCH 21/58] netty updated --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c888fb56c..a1c0f14bd 100644 --- a/pom.xml +++ b/pom.xml @@ -175,7 +175,7 @@ io.netty netty-bom - 4.1.85.Final + 4.1.86.Final pom import From bff2966b1b2bc4913d61720657b7b8447de8dc88 Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Tue, 13 Dec 2022 14:25:56 +0300 Subject: [PATCH 22/58] Add dependency to Marshalling codec. For some time --- redisson/pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/redisson/pom.xml b/redisson/pom.xml index 2fd31ea69..0372e495e 100644 --- a/redisson/pom.xml +++ b/redisson/pom.xml @@ -187,15 +187,19 @@ org.jboss.marshalling jboss-marshalling 2.0.11.Final + org.jboss.marshalling jboss-marshalling-river 2.0.11.Final + org.msgpack From 3b937e2a605d3c83737a621696ee08ff6c011fab Mon Sep 17 00:00:00 2001 From: Nicola Dardanis Date: Tue, 13 Dec 2022 14:34:21 +0100 Subject: [PATCH 23/58] feat: add evictions metrics support for RedissonCache Signed-off-by: Nicola Dardanis --- .../org/redisson/spring/cache/RedissonCache.java | 12 +++++++++++- .../redisson/spring/cache/RedissonCacheMetrics.java | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/redisson/src/main/java/org/redisson/spring/cache/RedissonCache.java b/redisson/src/main/java/org/redisson/spring/cache/RedissonCache.java index 4ae9922c2..cc46e3f09 100644 --- a/redisson/src/main/java/org/redisson/spring/cache/RedissonCache.java +++ b/redisson/src/main/java/org/redisson/spring/cache/RedissonCache.java @@ -46,6 +46,8 @@ public class RedissonCache implements Cache { private final AtomicLong puts = new AtomicLong(); private final AtomicLong misses = new AtomicLong(); + + private final AtomicLong evictions = new AtomicLong(); public RedissonCache(RMapCache mapCache, CacheConfig config, boolean allowNullValues) { this(mapCache, allowNullValues); @@ -144,7 +146,8 @@ public class RedissonCache implements Cache { @Override public void evict(Object key) { - map.fastRemove(key); + long delta = map.fastRemove(key); + addCacheEvictions(delta); } @Override @@ -238,6 +241,10 @@ public class RedissonCache implements Cache { long getCachePuts() { return puts.get(); } + + long getCacheEvictions() { + return evictions.get(); + } private void addCachePut() { puts.incrementAndGet(); @@ -251,4 +258,7 @@ public class RedissonCache implements Cache { misses.incrementAndGet(); } + private void addCacheEvictions(long delta) { + evictions.addAndGet(delta); + } } diff --git a/redisson/src/main/java/org/redisson/spring/cache/RedissonCacheMetrics.java b/redisson/src/main/java/org/redisson/spring/cache/RedissonCacheMetrics.java index c41b48846..819c52bdb 100644 --- a/redisson/src/main/java/org/redisson/spring/cache/RedissonCacheMetrics.java +++ b/redisson/src/main/java/org/redisson/spring/cache/RedissonCacheMetrics.java @@ -63,7 +63,7 @@ public class RedissonCacheMetrics extends CacheMeterBinder { @Override protected Long evictionCount() { - return null; + return cache.getCacheEvictions(); } @Override From 2554dea4a77b5ddf1a76f9792567bed3bc3ef688 Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Wed, 14 Dec 2022 08:44:31 +0300 Subject: [PATCH 24/58] Feature - implementation of Spring Cache methods added in Spring 5.2 #4740 --- .../java/org/redisson/spring/cache/RedissonCache.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/redisson/src/main/java/org/redisson/spring/cache/RedissonCache.java b/redisson/src/main/java/org/redisson/spring/cache/RedissonCache.java index cc46e3f09..831e4b4a2 100644 --- a/redisson/src/main/java/org/redisson/spring/cache/RedissonCache.java +++ b/redisson/src/main/java/org/redisson/spring/cache/RedissonCache.java @@ -146,8 +146,13 @@ public class RedissonCache implements Cache { @Override public void evict(Object key) { + evictIfPresent(key); + } + + public boolean evictIfPresent(Object key) { long delta = map.fastRemove(key); addCacheEvictions(delta); + return delta > 0; } @Override @@ -155,6 +160,10 @@ public class RedissonCache implements Cache { map.clear(); } + public boolean invalidate() { + return map.delete(); + } + private ValueWrapper toValueWrapper(Object value) { if (value == null) { return null; From f4e847906b28d3f7bd3f6412780f6b5502902e4c Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Wed, 14 Dec 2022 08:45:29 +0300 Subject: [PATCH 25/58] MarshallingCodec is deprecated now --- redisson/src/main/java/org/redisson/codec/MarshallingCodec.java | 1 + 1 file changed, 1 insertion(+) diff --git a/redisson/src/main/java/org/redisson/codec/MarshallingCodec.java b/redisson/src/main/java/org/redisson/codec/MarshallingCodec.java index 1d953762e..844b0830b 100644 --- a/redisson/src/main/java/org/redisson/codec/MarshallingCodec.java +++ b/redisson/src/main/java/org/redisson/codec/MarshallingCodec.java @@ -36,6 +36,7 @@ import java.util.Locale; * @author Nikita Koksharov * */ +@Deprecated public class MarshallingCodec extends BaseCodec { private final FastThreadLocal decoderThreadLocal = new FastThreadLocal() { From c80ceebeb4871449e302bc3c7371d671493ac660 Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Wed, 14 Dec 2022 11:07:51 +0300 Subject: [PATCH 26/58] Fixed - some scheduled tasks aren't executed (regression since 3.17.5) #4499 --- .../org/redisson/RedissonExecutorService.java | 6 ++--- .../RedissonExecutorRemoteService.java | 2 +- .../executor/ScheduledTasksService.java | 6 ++--- .../redisson/executor/TasksRunnerService.java | 8 +++--- .../org/redisson/executor/TasksService.java | 4 +-- .../remote/RemoteServiceResponse.java | 7 ++++-- .../RedissonScheduledExecutorServiceTest.java | 25 +++++++++++++++++-- 7 files changed, 41 insertions(+), 17 deletions(-) diff --git a/redisson/src/main/java/org/redisson/RedissonExecutorService.java b/redisson/src/main/java/org/redisson/RedissonExecutorService.java index cc9a05433..f02454d1f 100644 --- a/redisson/src/main/java/org/redisson/RedissonExecutorService.java +++ b/redisson/src/main/java/org/redisson/RedissonExecutorService.java @@ -261,10 +261,10 @@ public class RedissonExecutorService implements RScheduledExecutorService { + "for i = 1, #expiredTaskIds, 1 do " + "local name = expiredTaskIds[i];" + "local scheduledName = expiredTaskIds[i];" - + "if string.sub(scheduledName, 1, 2) ~= 'ff' then " - + "scheduledName = 'ff' .. scheduledName; " + + "if string.sub(scheduledName, 1, 3) ~= 'ff:' then " + + "scheduledName = 'ff:' .. scheduledName; " + "else " - + "name = string.sub(name, 3, string.len(name)); " + + "name = string.sub(name, 4, string.len(name)); " + "end;" + "redis.call('zadd', KEYS[2], startTime, scheduledName);" diff --git a/redisson/src/main/java/org/redisson/executor/RedissonExecutorRemoteService.java b/redisson/src/main/java/org/redisson/executor/RedissonExecutorRemoteService.java index ca3190bdb..eea651936 100644 --- a/redisson/src/main/java/org/redisson/executor/RedissonExecutorRemoteService.java +++ b/redisson/src/main/java/org/redisson/executor/RedissonExecutorRemoteService.java @@ -71,7 +71,7 @@ public class RedissonExecutorRemoteService extends RedissonRemoteService { + "redis.call('zrem', KEYS[2], ARGV[1]); " + "redis.call('zrem', KEYS[7], ARGV[1]); " - + "redis.call('zrem', KEYS[7], 'ff' .. ARGV[1]);" + + "redis.call('zrem', KEYS[7], 'ff:' .. ARGV[1]);" + "redis.call('hdel', KEYS[1], ARGV[1]); " + "if redis.call('decr', KEYS[3]) == 0 then " diff --git a/redisson/src/main/java/org/redisson/executor/ScheduledTasksService.java b/redisson/src/main/java/org/redisson/executor/ScheduledTasksService.java index 74bc25022..4ebe56149 100644 --- a/redisson/src/main/java/org/redisson/executor/ScheduledTasksService.java +++ b/redisson/src/main/java/org/redisson/executor/ScheduledTasksService.java @@ -62,11 +62,11 @@ public class ScheduledTasksService extends TasksService { + "local retryInterval = redis.call('get', KEYS[6]); " + "if retryInterval ~= false then " + "local time = tonumber(ARGV[1]) + tonumber(retryInterval);" - + "redis.call('zadd', KEYS[3], time, 'ff' .. ARGV[2]);" + + "redis.call('zadd', KEYS[3], time, 'ff:' .. ARGV[2]);" + "elseif tonumber(ARGV[4]) > 0 then " + "redis.call('set', KEYS[6], ARGV[4]);" + "local time = tonumber(ARGV[1]) + tonumber(ARGV[4]);" - + "redis.call('zadd', KEYS[3], time, 'ff' .. ARGV[2]);" + + "redis.call('zadd', KEYS[3], time, 'ff:' .. ARGV[2]);" + "end; " + "if tonumber(ARGV[5]) > 0 then " @@ -102,7 +102,7 @@ public class ScheduledTasksService extends TasksService { + "local task = redis.call('hget', KEYS[6], ARGV[1]); " + "redis.call('hdel', KEYS[6], ARGV[1]); " - + "redis.call('zrem', KEYS[2], 'ff' .. ARGV[1]); " + + "redis.call('zrem', KEYS[2], 'ff:' .. ARGV[1]); " + "redis.call('zrem', KEYS[8], ARGV[1]); " + "local removedScheduled = redis.call('zrem', KEYS[2], ARGV[1]); " diff --git a/redisson/src/main/java/org/redisson/executor/TasksRunnerService.java b/redisson/src/main/java/org/redisson/executor/TasksRunnerService.java index d454ebbad..005ab14f1 100644 --- a/redisson/src/main/java/org/redisson/executor/TasksRunnerService.java +++ b/redisson/src/main/java/org/redisson/executor/TasksRunnerService.java @@ -242,10 +242,10 @@ public class TasksRunnerService implements RemoteExecutorService { // check if executor service not in shutdown state "local name = ARGV[2];" + "local scheduledName = ARGV[2];" - + "if string.sub(scheduledName, 1, 2) ~= 'ff' then " - + "scheduledName = 'ff' .. scheduledName; " + + "if string.sub(scheduledName, 1, 3) ~= 'ff:' then " + + "scheduledName = 'ff:' .. scheduledName; " + "else " - + "name = string.sub(name, 3, string.len(name)); " + + "name = string.sub(name, 4, string.len(name)); " + "end;" + "local retryInterval = redis.call('get', KEYS[4]);" @@ -382,7 +382,7 @@ public class TasksRunnerService implements RemoteExecutorService { + "redis.call('hdel', KEYS[4], ARGV[3]); " + "end;"; } - script += "redis.call('zrem', KEYS[5], 'ff' .. ARGV[3]);" + + script += "redis.call('zrem', KEYS[5], 'ff:' .. ARGV[3]);" + "if redis.call('decr', KEYS[1]) == 0 then " + "redis.call('del', KEYS[1]);" + "if redis.call('get', KEYS[2]) == ARGV[1] then " diff --git a/redisson/src/main/java/org/redisson/executor/TasksService.java b/redisson/src/main/java/org/redisson/executor/TasksService.java index 8eb2f9ca3..110211969 100644 --- a/redisson/src/main/java/org/redisson/executor/TasksService.java +++ b/redisson/src/main/java/org/redisson/executor/TasksService.java @@ -133,7 +133,7 @@ public class TasksService extends BaseRemoteService { + "if tonumber(ARGV[1]) > 0 then " + "redis.call('set', KEYS[7], ARGV[4]);" - + "redis.call('zadd', KEYS[3], ARGV[1], 'ff' .. ARGV[2]);" + + "redis.call('zadd', KEYS[3], ARGV[1], 'ff:' .. ARGV[2]);" + "local v = redis.call('zrange', KEYS[3], 0, 0); " // if new task added to queue head then publish its startTime // to all scheduler workers @@ -157,7 +157,7 @@ public class TasksService extends BaseRemoteService { "return nil;" + "end;" + - "redis.call('zrem', KEYS[2], 'ff' .. ARGV[1]); " + "redis.call('zrem', KEYS[2], 'ff:' .. ARGV[1]); " + "redis.call('zrem', KEYS[8], ARGV[1]); " + "local task = redis.call('hget', KEYS[6], ARGV[1]); " + "redis.call('hdel', KEYS[6], ARGV[1]); " diff --git a/redisson/src/main/java/org/redisson/remote/RemoteServiceResponse.java b/redisson/src/main/java/org/redisson/remote/RemoteServiceResponse.java index 03efabc3b..68f18f682 100644 --- a/redisson/src/main/java/org/redisson/remote/RemoteServiceResponse.java +++ b/redisson/src/main/java/org/redisson/remote/RemoteServiceResponse.java @@ -58,7 +58,10 @@ public class RemoteServiceResponse implements RRemoteServiceResponse, Serializab @Override public String toString() { - return "RemoteServiceResponse [result=" + result + ", error=" + error + "]"; + return "RemoteServiceResponse{" + + "result=" + result + + ", error=" + error + + ", id='" + id + '\'' + + '}'; } - } diff --git a/redisson/src/test/java/org/redisson/executor/RedissonScheduledExecutorServiceTest.java b/redisson/src/test/java/org/redisson/executor/RedissonScheduledExecutorServiceTest.java index 58d4dafb3..5473aeacd 100644 --- a/redisson/src/test/java/org/redisson/executor/RedissonScheduledExecutorServiceTest.java +++ b/redisson/src/test/java/org/redisson/executor/RedissonScheduledExecutorServiceTest.java @@ -24,6 +24,7 @@ import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; @@ -91,6 +92,24 @@ public class RedissonScheduledExecutorServiceTest extends BaseTest { } + @Test + public void testTasksExecution() throws InterruptedException { + RScheduledExecutorService executorService = redisson.getExecutorService("test"); + + Map> futureMap = new ConcurrentHashMap<>(); + for (int i = 0; i < 1000; i++) { + RScheduledFuture s = executorService.schedule(new IncrementRunnableTask(), + ThreadLocalRandom.current().nextInt(500), TimeUnit.MILLISECONDS); + futureMap.put(s.getTaskId(), s); + s.whenComplete((r, e) -> { + futureMap.remove(s.getTaskId()); + }); + } + + Thread.sleep(2000); + assertThat(futureMap).hasSize(0); + } + @Test public void testScheduleAtFixedRate() throws InterruptedException { RScheduledExecutorService executorService = redisson.getExecutorService("test"); @@ -198,6 +217,7 @@ public class RedissonScheduledExecutorServiceTest extends BaseTest { @Test public void testTaskFailover() throws Exception { AtomicInteger counter = new AtomicInteger(); + // don't allow to mark task as completed new MockUp() { @Mock void finish(Invocation invocation, String requestId, boolean removeTask) { @@ -214,7 +234,8 @@ public class RedissonScheduledExecutorServiceTest extends BaseTest { node = RedissonNode.create(nodeConfig); node.start(); - RScheduledExecutorService executor = redisson.getExecutorService("test2", ExecutorOptions.defaults().taskRetryInterval(10, TimeUnit.SECONDS)); + RScheduledExecutorService executor = redisson.getExecutorService("test2", + ExecutorOptions.defaults().taskRetryInterval(10, TimeUnit.SECONDS)); long start = System.currentTimeMillis(); RExecutorFuture f = executor.schedule(new IncrementRunnableTask("counter"), 1, TimeUnit.SECONDS); f.toCompletableFuture().join(); @@ -233,7 +254,7 @@ public class RedissonScheduledExecutorServiceTest extends BaseTest { assertThat(redisson.getAtomicLong("counter").get()).isEqualTo(2); redisson.getKeys().delete("counter"); - assertThat(redisson.getKeys().count()).isEqualTo(1); + assertThat(redisson.getKeys().count()).isEqualTo(2); } @Test From c748702911deb87c5bdff988aaded263810c7681 Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Wed, 14 Dec 2022 11:15:22 +0300 Subject: [PATCH 27/58] test fixed --- .../redisson/executor/RedissonScheduledExecutorServiceTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redisson/src/test/java/org/redisson/executor/RedissonScheduledExecutorServiceTest.java b/redisson/src/test/java/org/redisson/executor/RedissonScheduledExecutorServiceTest.java index 5473aeacd..74be801b8 100644 --- a/redisson/src/test/java/org/redisson/executor/RedissonScheduledExecutorServiceTest.java +++ b/redisson/src/test/java/org/redisson/executor/RedissonScheduledExecutorServiceTest.java @@ -254,7 +254,7 @@ public class RedissonScheduledExecutorServiceTest extends BaseTest { assertThat(redisson.getAtomicLong("counter").get()).isEqualTo(2); redisson.getKeys().delete("counter"); - assertThat(redisson.getKeys().count()).isEqualTo(2); + assertThat(redisson.getKeys().count()).isEqualTo(1); } @Test From 6e501b0767aaca9c601a35c299e33c2c2f362250 Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Wed, 14 Dec 2022 11:19:06 +0300 Subject: [PATCH 28/58] test fixed --- .../java/org/redisson/executor/RedissonExecutorServiceTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redisson/src/test/java/org/redisson/executor/RedissonExecutorServiceTest.java b/redisson/src/test/java/org/redisson/executor/RedissonExecutorServiceTest.java index 77c945840..4490d45a0 100644 --- a/redisson/src/test/java/org/redisson/executor/RedissonExecutorServiceTest.java +++ b/redisson/src/test/java/org/redisson/executor/RedissonExecutorServiceTest.java @@ -318,7 +318,7 @@ public class RedissonExecutorServiceTest extends BaseTest { RExecutorFuture future = executor.submit(new TestClass()); future.get(); String id = redisson.getBucket("id").get(); - assertThat(id).hasSize(34); + assertThat(future.getTaskId()).isEqualTo(id); } @Test From 934c624aee01769941c6f4db51c95afdfe648148 Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Wed, 14 Dec 2022 12:56:58 +0300 Subject: [PATCH 29/58] Fixed - codec,nettyHook,addressResolverGroupFactory,connectionListener settings can't be defined through Micronaut config #4741 --- .../micronaut/RedissonConfiguration.java | 65 ++++++++++++++++++ .../micronaut/RedissonConfiguration.java | 68 +++++++++++++++++++ 2 files changed, 133 insertions(+) diff --git a/redisson-micronaut/redisson-micronaut-20/src/main/java/org/redisson/micronaut/RedissonConfiguration.java b/redisson-micronaut/redisson-micronaut-20/src/main/java/org/redisson/micronaut/RedissonConfiguration.java index 51b9bc568..865c7381d 100644 --- a/redisson-micronaut/redisson-micronaut-20/src/main/java/org/redisson/micronaut/RedissonConfiguration.java +++ b/redisson-micronaut/redisson-micronaut-20/src/main/java/org/redisson/micronaut/RedissonConfiguration.java @@ -18,7 +18,11 @@ package org.redisson.micronaut; import io.micronaut.context.annotation.ConfigurationBuilder; import io.micronaut.context.annotation.ConfigurationProperties; import io.micronaut.context.annotation.Requires; +import org.redisson.client.NettyHook; +import org.redisson.client.codec.Codec; import org.redisson.config.*; +import org.redisson.connection.AddressResolverGroupFactory; +import org.redisson.connection.ConnectionListener; /** * @@ -110,4 +114,65 @@ public class RedissonConfiguration extends Config { protected void setMasterSlaveServersConfig(MasterSlaveServersConfig masterSlaveConnectionConfig) { super.setMasterSlaveServersConfig(masterSlaveConnectionConfig); } + + @Override + @ConfigurationBuilder(value = "codec1") + public Config setCodec(Codec codec) { + return super.setCodec(codec); + } + + public Config setCodec(String className) { + try { + Codec codec = (Codec) Class.forName(className).getDeclaredConstructor().newInstance(); + return super.setCodec(codec); + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + } + + @Override + @ConfigurationBuilder(value = "nettyHook1") + public Config setNettyHook(NettyHook nettyHook) { + return super.setNettyHook(nettyHook); + } + + public Config setNettyHook(String className) { + try { + NettyHook nettyHook = (NettyHook) Class.forName(className).getDeclaredConstructor().newInstance(); + return super.setNettyHook(nettyHook); + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + } + + @Override + @ConfigurationBuilder(value = "addressResolverGroupFactory1") + public Config setAddressResolverGroupFactory(AddressResolverGroupFactory addressResolverGroupFactory) { + return super.setAddressResolverGroupFactory(addressResolverGroupFactory); + } + + public Config setAddressResolverGroupFactory(String className) { + try { + AddressResolverGroupFactory value = (AddressResolverGroupFactory) Class.forName(className).getDeclaredConstructor().newInstance(); + return super.setAddressResolverGroupFactory(value); + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + } + + @Override + @ConfigurationBuilder(value = "connectionListener1") + public Config setConnectionListener(ConnectionListener connectionListener) { + return super.setConnectionListener(connectionListener); + } + + public Config setConnectionListener(String className) { + try { + ConnectionListener connectionListener = (ConnectionListener) Class.forName(className).getDeclaredConstructor().newInstance(); + return super.setConnectionListener(connectionListener); + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + } + } diff --git a/redisson-micronaut/redisson-micronaut-30/src/main/java/org/redisson/micronaut/RedissonConfiguration.java b/redisson-micronaut/redisson-micronaut-30/src/main/java/org/redisson/micronaut/RedissonConfiguration.java index 51b9bc568..e30921aec 100644 --- a/redisson-micronaut/redisson-micronaut-30/src/main/java/org/redisson/micronaut/RedissonConfiguration.java +++ b/redisson-micronaut/redisson-micronaut-30/src/main/java/org/redisson/micronaut/RedissonConfiguration.java @@ -17,8 +17,15 @@ package org.redisson.micronaut; import io.micronaut.context.annotation.ConfigurationBuilder; import io.micronaut.context.annotation.ConfigurationProperties; +import io.micronaut.context.annotation.Parameter; import io.micronaut.context.annotation.Requires; +import org.redisson.client.NettyHook; +import org.redisson.client.codec.Codec; import org.redisson.config.*; +import org.redisson.connection.AddressResolverGroupFactory; +import org.redisson.connection.ConnectionListener; + +import java.lang.reflect.InvocationTargetException; /** * @@ -110,4 +117,65 @@ public class RedissonConfiguration extends Config { protected void setMasterSlaveServersConfig(MasterSlaveServersConfig masterSlaveConnectionConfig) { super.setMasterSlaveServersConfig(masterSlaveConnectionConfig); } + + @Override + @ConfigurationBuilder(value = "codec1") + public Config setCodec(Codec codec) { + return super.setCodec(codec); + } + + public Config setCodec(String className) { + try { + Codec codec = (Codec) Class.forName(className).getDeclaredConstructor().newInstance(); + return super.setCodec(codec); + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + } + + @Override + @ConfigurationBuilder(value = "nettyHook1") + public Config setNettyHook(NettyHook nettyHook) { + return super.setNettyHook(nettyHook); + } + + public Config setNettyHook(String className) { + try { + NettyHook nettyHook = (NettyHook) Class.forName(className).getDeclaredConstructor().newInstance(); + return super.setNettyHook(nettyHook); + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + } + + @Override + @ConfigurationBuilder(value = "addressResolverGroupFactory1") + public Config setAddressResolverGroupFactory(AddressResolverGroupFactory addressResolverGroupFactory) { + return super.setAddressResolverGroupFactory(addressResolverGroupFactory); + } + + public Config setAddressResolverGroupFactory(String className) { + try { + AddressResolverGroupFactory value = (AddressResolverGroupFactory) Class.forName(className).getDeclaredConstructor().newInstance(); + return super.setAddressResolverGroupFactory(value); + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + } + + @Override + @ConfigurationBuilder(value = "connectionListener1") + public Config setConnectionListener(ConnectionListener connectionListener) { + return super.setConnectionListener(connectionListener); + } + + public Config setConnectionListener(String className) { + try { + ConnectionListener connectionListener = (ConnectionListener) Class.forName(className).getDeclaredConstructor().newInstance(); + return super.setConnectionListener(connectionListener); + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + } + } From f72e6a3cf2159a996ba655abcfbfb01da9f5072a Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Fri, 16 Dec 2022 10:32:02 +0300 Subject: [PATCH 30/58] Fixed - new Redis node isn't discovered between PubSub subscription attempts #4745 --- .../pubsub/PublishSubscribeService.java | 72 ++++++++++--------- 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/redisson/src/main/java/org/redisson/pubsub/PublishSubscribeService.java b/redisson/src/main/java/org/redisson/pubsub/PublishSubscribeService.java index c76b6b743..177bab2d3 100644 --- a/redisson/src/main/java/org/redisson/pubsub/PublishSubscribeService.java +++ b/redisson/src/main/java/org/redisson/pubsub/PublishSubscribeService.java @@ -269,6 +269,37 @@ public class PublishSubscribeService { }); } + private void trySubscribe(Codec codec, ChannelName channelName, + CompletableFuture promise, PubSubType type, + AsyncSemaphore lock, AtomicInteger attempts, RedisPubSubListener... listeners) { + if (attempts.get() == config.getRetryAttempts()) { + lock.release(); + MasterSlaveEntry entry = getEntry(channelName); + if (entry == null) { + RedisNodeNotFoundException ex = new RedisNodeNotFoundException("Node for name: " + channelName + " hasn't been discovered yet. Check cluster slots coverage using CLUSTER NODES command. Increase value of retryAttempts and/or retryInterval settings."); + promise.completeExceptionally(ex); + return; + } + + promise.completeExceptionally(new RedisTimeoutException( + "Unable to acquire connection for subscription after " + attempts.get() + " attempts. " + + "Increase 'subscriptionsPerConnection' and/or 'subscriptionConnectionPoolSize' parameters.")); + return; + } + + attempts.incrementAndGet(); + + MasterSlaveEntry entry = getEntry(channelName); + if (entry == null) { + connectionManager.newTimeout(tt -> { + trySubscribe(codec, channelName, promise, type, lock, attempts, listeners); + }, config.getRetryInterval(), TimeUnit.MILLISECONDS); + return; + } + + subscribeNoTimeout(codec, channelName, entry, promise, type, lock, attempts, listeners); + } + private void subscribeNoTimeout(Codec codec, ChannelName channelName, MasterSlaveEntry entry, CompletableFuture promise, PubSubType type, AsyncSemaphore lock, AtomicInteger attempts, RedisPubSubListener... listeners) { @@ -285,26 +316,19 @@ public class PublishSubscribeService { return; } - MasterSlaveEntry msEntry = Optional.ofNullable(connectionManager.getEntry(entry.getClient())).orElse(entry); - PubSubEntry freePubSubConnections = entry2PubSubConnection.getOrDefault(msEntry, new PubSubEntry()); + PubSubEntry freePubSubConnections = entry2PubSubConnection.getOrDefault(entry, new PubSubEntry()); PubSubConnectionEntry freeEntry = freePubSubConnections.getEntries().peek(); if (freeEntry == null) { freePubSubLock.release(); - CompletableFuture connectFuture = connect(codec, channelName, msEntry, promise, type, lock, listeners); + CompletableFuture connectFuture = connect(codec, channelName, entry, promise, type, lock, listeners); connectionManager.newTimeout(t -> { - if (attempts.get() == config.getRetryAttempts()) { - connectFuture.completeExceptionally(new RedisTimeoutException( - "Unable to acquire connection for subscription after " + attempts.get() + " attempts. " + - "Increase 'subscriptionsPerConnection' and/or 'subscriptionConnectionPoolSize' parameters.")); + if (!connectFuture.cancel(false)) { return; } - if (connectFuture.cancel(true)) { - subscribe(codec, channelName, entry, promise, type, lock, attempts, listeners); - attempts.incrementAndGet(); - } + trySubscribe(codec, channelName, promise, type, lock, attempts, listeners); }, config.getRetryInterval(), TimeUnit.MILLISECONDS); return; } @@ -314,7 +338,7 @@ public class PublishSubscribeService { throw new IllegalStateException(); } - PubSubKey key = new PubSubKey(channelName, msEntry); + PubSubKey key = new PubSubKey(channelName, entry); PubSubConnectionEntry oldEntry = name2PubSubConnection.putIfAbsent(key, freeEntry); if (oldEntry != null) { freeEntry.release(); @@ -379,38 +403,18 @@ public class PublishSubscribeService { return subscribeFuture; } - private CompletableFuture nextPubSubConnection(MasterSlaveEntry entry, ChannelName channelName) { - if (entry == null) { - int slot = connectionManager.calcSlot(channelName.getName()); - RedisNodeNotFoundException ex = new RedisNodeNotFoundException("Node for slot: " + slot + " hasn't been discovered yet. Check cluster slots coverage using CLUSTER NODES command. Increase value of retryAttempts and/or retryInterval settings."); - CompletableFuture result = new CompletableFuture<>(); - result.completeExceptionally(ex); - return result; - } - return entry.nextPubSubConnection(); - } - private CompletableFuture connect(Codec codec, ChannelName channelName, MasterSlaveEntry msEntry, CompletableFuture promise, PubSubType type, AsyncSemaphore lock, RedisPubSubListener... listeners) { - CompletableFuture connFuture = nextPubSubConnection(msEntry, channelName); + CompletableFuture connFuture = msEntry.nextPubSubConnection(); promise.whenComplete((res, e) -> { if (e != null) { connFuture.completeExceptionally(e); } }); - connFuture.whenComplete((conn, ex) -> { - if (ex != null) { -// freePubSubLock.release(); - lock.release(); - if (!connFuture.isCancelled()) { - promise.completeExceptionally(ex); - } - return; - } - + connFuture.thenAccept(conn -> { freePubSubLock.acquire().thenAccept(c -> { PubSubConnectionEntry entry = new PubSubConnectionEntry(conn, connectionManager); int remainFreeAmount = entry.tryAcquire(); From 0c402d478a46dcf382ca85f7af213bd66eb98954 Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Fri, 16 Dec 2022 10:40:39 +0300 Subject: [PATCH 31/58] Fixed - new Redis node isn't discovered between PubSub subscription attempts #4745 --- .../main/java/org/redisson/pubsub/PublishSubscribeService.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/redisson/src/main/java/org/redisson/pubsub/PublishSubscribeService.java b/redisson/src/main/java/org/redisson/pubsub/PublishSubscribeService.java index 177bab2d3..a030c1063 100644 --- a/redisson/src/main/java/org/redisson/pubsub/PublishSubscribeService.java +++ b/redisson/src/main/java/org/redisson/pubsub/PublishSubscribeService.java @@ -324,7 +324,8 @@ public class PublishSubscribeService { CompletableFuture connectFuture = connect(codec, channelName, entry, promise, type, lock, listeners); connectionManager.newTimeout(t -> { - if (!connectFuture.cancel(false)) { + if (!connectFuture.cancel(false) + && !connectFuture.isCompletedExceptionally()) { return; } From cb305d35bb5fc3678e825cc3d7ed6009b721c552 Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Fri, 16 Dec 2022 12:18:16 +0300 Subject: [PATCH 32/58] [maven-release-plugin] prepare release redisson-3.19.0 --- pom.xml | 4 ++-- redisson-all/pom.xml | 4 ++-- redisson-helidon/pom.xml | 2 +- redisson-helidon/redisson-helidon-20/pom.xml | 2 +- redisson-helidon/redisson-helidon-30/pom.xml | 2 +- redisson-hibernate/pom.xml | 2 +- redisson-hibernate/redisson-hibernate-4/pom.xml | 2 +- redisson-hibernate/redisson-hibernate-5/pom.xml | 2 +- redisson-hibernate/redisson-hibernate-52/pom.xml | 2 +- redisson-hibernate/redisson-hibernate-53/pom.xml | 2 +- redisson-hibernate/redisson-hibernate-6/pom.xml | 2 +- redisson-micronaut/pom.xml | 2 +- redisson-micronaut/redisson-micronaut-20/pom.xml | 2 +- redisson-micronaut/redisson-micronaut-30/pom.xml | 2 +- redisson-mybatis/pom.xml | 2 +- redisson-quarkus/pom.xml | 2 +- redisson-quarkus/redisson-quarkus-16/deployment/pom.xml | 2 +- .../redisson-quarkus-16/integration-tests/pom.xml | 2 +- redisson-quarkus/redisson-quarkus-16/pom.xml | 2 +- redisson-quarkus/redisson-quarkus-16/runtime/pom.xml | 2 +- redisson-quarkus/redisson-quarkus-20/deployment/pom.xml | 2 +- .../redisson-quarkus-20/integration-tests/pom.xml | 2 +- redisson-quarkus/redisson-quarkus-20/pom.xml | 2 +- redisson-quarkus/redisson-quarkus-20/runtime/pom.xml | 2 +- redisson-spring-boot-starter/pom.xml | 2 +- redisson-spring-data/pom.xml | 2 +- redisson-spring-data/redisson-spring-data-16/pom.xml | 2 +- redisson-spring-data/redisson-spring-data-17/pom.xml | 2 +- redisson-spring-data/redisson-spring-data-18/pom.xml | 2 +- redisson-spring-data/redisson-spring-data-20/pom.xml | 2 +- redisson-spring-data/redisson-spring-data-21/pom.xml | 2 +- redisson-spring-data/redisson-spring-data-22/pom.xml | 2 +- redisson-spring-data/redisson-spring-data-23/pom.xml | 2 +- redisson-spring-data/redisson-spring-data-24/pom.xml | 2 +- redisson-spring-data/redisson-spring-data-25/pom.xml | 2 +- redisson-spring-data/redisson-spring-data-26/pom.xml | 2 +- redisson-spring-data/redisson-spring-data-27/pom.xml | 2 +- redisson-spring-data/redisson-spring-data-30/pom.xml | 2 +- redisson-tomcat/pom.xml | 2 +- redisson-tomcat/redisson-tomcat-10/pom.xml | 2 +- redisson-tomcat/redisson-tomcat-7/pom.xml | 2 +- redisson-tomcat/redisson-tomcat-8/pom.xml | 2 +- redisson-tomcat/redisson-tomcat-9/pom.xml | 2 +- redisson/pom.xml | 2 +- 44 files changed, 46 insertions(+), 46 deletions(-) diff --git a/pom.xml b/pom.xml index a1c0f14bd..a84ecbf69 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ org.redisson redisson-parent - 3.18.2-SNAPSHOT + 3.19.0 pom Redisson @@ -29,7 +29,7 @@ scm:git:git@github.com:redisson/redisson.git scm:git:git@github.com:redisson/redisson.git scm:git:git@github.com:redisson/redisson.git - HEAD + redisson-3.19.0 diff --git a/redisson-all/pom.xml b/redisson-all/pom.xml index 79e84be11..ec0d5d697 100644 --- a/redisson-all/pom.xml +++ b/redisson-all/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-parent - 3.18.2-SNAPSHOT + 3.19.0 ../ @@ -26,7 +26,7 @@ scm:git:git@github.com:mrniko/redisson.git scm:git:git@github.com:mrniko/redisson.git scm:git:git@github.com:mrniko/redisson.git - redisson-parent-0.9.0 + redisson-3.19.0 diff --git a/redisson-helidon/pom.xml b/redisson-helidon/pom.xml index 979b97ec6..5f1ad9ef9 100644 --- a/redisson-helidon/pom.xml +++ b/redisson-helidon/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-parent - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-helidon/redisson-helidon-20/pom.xml b/redisson-helidon/redisson-helidon-20/pom.xml index 03171a1b7..aa8961d3d 100644 --- a/redisson-helidon/redisson-helidon-20/pom.xml +++ b/redisson-helidon/redisson-helidon-20/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-helidon - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-helidon/redisson-helidon-30/pom.xml b/redisson-helidon/redisson-helidon-30/pom.xml index 401c6ef19..adc4af9a2 100644 --- a/redisson-helidon/redisson-helidon-30/pom.xml +++ b/redisson-helidon/redisson-helidon-30/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-helidon - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-hibernate/pom.xml b/redisson-hibernate/pom.xml index 76b674d31..7de17eb34 100644 --- a/redisson-hibernate/pom.xml +++ b/redisson-hibernate/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-parent - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-hibernate/redisson-hibernate-4/pom.xml b/redisson-hibernate/redisson-hibernate-4/pom.xml index 36b5ce403..9dd4d8325 100644 --- a/redisson-hibernate/redisson-hibernate-4/pom.xml +++ b/redisson-hibernate/redisson-hibernate-4/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-hibernate - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-hibernate/redisson-hibernate-5/pom.xml b/redisson-hibernate/redisson-hibernate-5/pom.xml index 817fc9241..3abfa74e7 100644 --- a/redisson-hibernate/redisson-hibernate-5/pom.xml +++ b/redisson-hibernate/redisson-hibernate-5/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-hibernate - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-hibernate/redisson-hibernate-52/pom.xml b/redisson-hibernate/redisson-hibernate-52/pom.xml index f78eb8bc3..1843abd73 100644 --- a/redisson-hibernate/redisson-hibernate-52/pom.xml +++ b/redisson-hibernate/redisson-hibernate-52/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-hibernate - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-hibernate/redisson-hibernate-53/pom.xml b/redisson-hibernate/redisson-hibernate-53/pom.xml index 9c6873708..91167a596 100644 --- a/redisson-hibernate/redisson-hibernate-53/pom.xml +++ b/redisson-hibernate/redisson-hibernate-53/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-hibernate - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-hibernate/redisson-hibernate-6/pom.xml b/redisson-hibernate/redisson-hibernate-6/pom.xml index 6ce4cc60d..6d4506527 100644 --- a/redisson-hibernate/redisson-hibernate-6/pom.xml +++ b/redisson-hibernate/redisson-hibernate-6/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-hibernate - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-micronaut/pom.xml b/redisson-micronaut/pom.xml index 621fc01e3..eccde3b4e 100644 --- a/redisson-micronaut/pom.xml +++ b/redisson-micronaut/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-parent - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-micronaut/redisson-micronaut-20/pom.xml b/redisson-micronaut/redisson-micronaut-20/pom.xml index ccb6a3b92..14ae5fba4 100644 --- a/redisson-micronaut/redisson-micronaut-20/pom.xml +++ b/redisson-micronaut/redisson-micronaut-20/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-micronaut - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-micronaut/redisson-micronaut-30/pom.xml b/redisson-micronaut/redisson-micronaut-30/pom.xml index 5e4e48fe9..60274ee63 100644 --- a/redisson-micronaut/redisson-micronaut-30/pom.xml +++ b/redisson-micronaut/redisson-micronaut-30/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-micronaut - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-mybatis/pom.xml b/redisson-mybatis/pom.xml index d9c7c0021..f6642f073 100644 --- a/redisson-mybatis/pom.xml +++ b/redisson-mybatis/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-parent - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-quarkus/pom.xml b/redisson-quarkus/pom.xml index 9b07af45b..da45704be 100644 --- a/redisson-quarkus/pom.xml +++ b/redisson-quarkus/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-parent - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-quarkus/redisson-quarkus-16/deployment/pom.xml b/redisson-quarkus/redisson-quarkus-16/deployment/pom.xml index 0d57940b7..0a7205c6a 100644 --- a/redisson-quarkus/redisson-quarkus-16/deployment/pom.xml +++ b/redisson-quarkus/redisson-quarkus-16/deployment/pom.xml @@ -5,7 +5,7 @@ org.redisson redisson-quarkus-16-parent - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-quarkus/redisson-quarkus-16/integration-tests/pom.xml b/redisson-quarkus/redisson-quarkus-16/integration-tests/pom.xml index 6a6435ab9..624e34d90 100644 --- a/redisson-quarkus/redisson-quarkus-16/integration-tests/pom.xml +++ b/redisson-quarkus/redisson-quarkus-16/integration-tests/pom.xml @@ -5,7 +5,7 @@ org.redisson redisson-quarkus-16-parent - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-quarkus/redisson-quarkus-16/pom.xml b/redisson-quarkus/redisson-quarkus-16/pom.xml index 01e50553e..21bb0b438 100644 --- a/redisson-quarkus/redisson-quarkus-16/pom.xml +++ b/redisson-quarkus/redisson-quarkus-16/pom.xml @@ -21,7 +21,7 @@ org.redisson redisson-quarkus - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-quarkus/redisson-quarkus-16/runtime/pom.xml b/redisson-quarkus/redisson-quarkus-16/runtime/pom.xml index c4290e510..3086bed3e 100644 --- a/redisson-quarkus/redisson-quarkus-16/runtime/pom.xml +++ b/redisson-quarkus/redisson-quarkus-16/runtime/pom.xml @@ -5,7 +5,7 @@ org.redisson redisson-quarkus-16-parent - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-quarkus/redisson-quarkus-20/deployment/pom.xml b/redisson-quarkus/redisson-quarkus-20/deployment/pom.xml index f27786dd9..d283c021a 100644 --- a/redisson-quarkus/redisson-quarkus-20/deployment/pom.xml +++ b/redisson-quarkus/redisson-quarkus-20/deployment/pom.xml @@ -5,7 +5,7 @@ org.redisson redisson-quarkus-20-parent - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-quarkus/redisson-quarkus-20/integration-tests/pom.xml b/redisson-quarkus/redisson-quarkus-20/integration-tests/pom.xml index 262d02178..c358734b2 100644 --- a/redisson-quarkus/redisson-quarkus-20/integration-tests/pom.xml +++ b/redisson-quarkus/redisson-quarkus-20/integration-tests/pom.xml @@ -5,7 +5,7 @@ org.redisson redisson-quarkus-20-parent - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-quarkus/redisson-quarkus-20/pom.xml b/redisson-quarkus/redisson-quarkus-20/pom.xml index 9d6b73def..0562d4b3e 100644 --- a/redisson-quarkus/redisson-quarkus-20/pom.xml +++ b/redisson-quarkus/redisson-quarkus-20/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-quarkus - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-quarkus/redisson-quarkus-20/runtime/pom.xml b/redisson-quarkus/redisson-quarkus-20/runtime/pom.xml index ade4581fa..e1fff96ba 100644 --- a/redisson-quarkus/redisson-quarkus-20/runtime/pom.xml +++ b/redisson-quarkus/redisson-quarkus-20/runtime/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-quarkus-20-parent - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-spring-boot-starter/pom.xml b/redisson-spring-boot-starter/pom.xml index ba075b377..d49ce5f38 100644 --- a/redisson-spring-boot-starter/pom.xml +++ b/redisson-spring-boot-starter/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-parent - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-spring-data/pom.xml b/redisson-spring-data/pom.xml index 8e2f59118..b10956f91 100644 --- a/redisson-spring-data/pom.xml +++ b/redisson-spring-data/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-parent - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-spring-data/redisson-spring-data-16/pom.xml b/redisson-spring-data/redisson-spring-data-16/pom.xml index 4eaab0ad6..baa161550 100644 --- a/redisson-spring-data/redisson-spring-data-16/pom.xml +++ b/redisson-spring-data/redisson-spring-data-16/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-spring-data - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-spring-data/redisson-spring-data-17/pom.xml b/redisson-spring-data/redisson-spring-data-17/pom.xml index b0656c941..54cd5210a 100644 --- a/redisson-spring-data/redisson-spring-data-17/pom.xml +++ b/redisson-spring-data/redisson-spring-data-17/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-spring-data - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-spring-data/redisson-spring-data-18/pom.xml b/redisson-spring-data/redisson-spring-data-18/pom.xml index a00a63721..bd471418f 100644 --- a/redisson-spring-data/redisson-spring-data-18/pom.xml +++ b/redisson-spring-data/redisson-spring-data-18/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-spring-data - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-spring-data/redisson-spring-data-20/pom.xml b/redisson-spring-data/redisson-spring-data-20/pom.xml index 5839a5e8e..8b32b4a17 100644 --- a/redisson-spring-data/redisson-spring-data-20/pom.xml +++ b/redisson-spring-data/redisson-spring-data-20/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-spring-data - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-spring-data/redisson-spring-data-21/pom.xml b/redisson-spring-data/redisson-spring-data-21/pom.xml index d09dd83ca..5ce9e3a1b 100644 --- a/redisson-spring-data/redisson-spring-data-21/pom.xml +++ b/redisson-spring-data/redisson-spring-data-21/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-spring-data - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-spring-data/redisson-spring-data-22/pom.xml b/redisson-spring-data/redisson-spring-data-22/pom.xml index ef8835771..44e3448c7 100644 --- a/redisson-spring-data/redisson-spring-data-22/pom.xml +++ b/redisson-spring-data/redisson-spring-data-22/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-spring-data - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-spring-data/redisson-spring-data-23/pom.xml b/redisson-spring-data/redisson-spring-data-23/pom.xml index c59a56d81..0601e75bd 100644 --- a/redisson-spring-data/redisson-spring-data-23/pom.xml +++ b/redisson-spring-data/redisson-spring-data-23/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-spring-data - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-spring-data/redisson-spring-data-24/pom.xml b/redisson-spring-data/redisson-spring-data-24/pom.xml index 5c67c9f5f..35c19e3f8 100644 --- a/redisson-spring-data/redisson-spring-data-24/pom.xml +++ b/redisson-spring-data/redisson-spring-data-24/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-spring-data - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-spring-data/redisson-spring-data-25/pom.xml b/redisson-spring-data/redisson-spring-data-25/pom.xml index 62eac9c40..81483832e 100644 --- a/redisson-spring-data/redisson-spring-data-25/pom.xml +++ b/redisson-spring-data/redisson-spring-data-25/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-spring-data - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-spring-data/redisson-spring-data-26/pom.xml b/redisson-spring-data/redisson-spring-data-26/pom.xml index 5e87fb86f..bf268d840 100644 --- a/redisson-spring-data/redisson-spring-data-26/pom.xml +++ b/redisson-spring-data/redisson-spring-data-26/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-spring-data - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-spring-data/redisson-spring-data-27/pom.xml b/redisson-spring-data/redisson-spring-data-27/pom.xml index 23a578ce4..685fa5fff 100644 --- a/redisson-spring-data/redisson-spring-data-27/pom.xml +++ b/redisson-spring-data/redisson-spring-data-27/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-spring-data - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-spring-data/redisson-spring-data-30/pom.xml b/redisson-spring-data/redisson-spring-data-30/pom.xml index 558808a63..a54c45463 100644 --- a/redisson-spring-data/redisson-spring-data-30/pom.xml +++ b/redisson-spring-data/redisson-spring-data-30/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-spring-data - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-tomcat/pom.xml b/redisson-tomcat/pom.xml index 7e51a7bfa..09b183f30 100644 --- a/redisson-tomcat/pom.xml +++ b/redisson-tomcat/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-parent - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-tomcat/redisson-tomcat-10/pom.xml b/redisson-tomcat/redisson-tomcat-10/pom.xml index 3be73f45b..6d2e7514b 100644 --- a/redisson-tomcat/redisson-tomcat-10/pom.xml +++ b/redisson-tomcat/redisson-tomcat-10/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-tomcat - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-tomcat/redisson-tomcat-7/pom.xml b/redisson-tomcat/redisson-tomcat-7/pom.xml index 459c84f35..04e217618 100644 --- a/redisson-tomcat/redisson-tomcat-7/pom.xml +++ b/redisson-tomcat/redisson-tomcat-7/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-tomcat - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-tomcat/redisson-tomcat-8/pom.xml b/redisson-tomcat/redisson-tomcat-8/pom.xml index fbecff131..d98abf31f 100644 --- a/redisson-tomcat/redisson-tomcat-8/pom.xml +++ b/redisson-tomcat/redisson-tomcat-8/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-tomcat - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson-tomcat/redisson-tomcat-9/pom.xml b/redisson-tomcat/redisson-tomcat-9/pom.xml index 73c7828b3..7acfc677c 100644 --- a/redisson-tomcat/redisson-tomcat-9/pom.xml +++ b/redisson-tomcat/redisson-tomcat-9/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-tomcat - 3.18.2-SNAPSHOT + 3.19.0 ../ diff --git a/redisson/pom.xml b/redisson/pom.xml index 0372e495e..591a23b94 100644 --- a/redisson/pom.xml +++ b/redisson/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-parent - 3.18.2-SNAPSHOT + 3.19.0 ../ From 003e878db83ee405d61b111f612e31abd0d377fe Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Fri, 16 Dec 2022 12:18:22 +0300 Subject: [PATCH 33/58] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- redisson-all/pom.xml | 4 ++-- redisson-helidon/pom.xml | 2 +- redisson-helidon/redisson-helidon-20/pom.xml | 2 +- redisson-helidon/redisson-helidon-30/pom.xml | 2 +- redisson-hibernate/pom.xml | 2 +- redisson-hibernate/redisson-hibernate-4/pom.xml | 2 +- redisson-hibernate/redisson-hibernate-5/pom.xml | 2 +- redisson-hibernate/redisson-hibernate-52/pom.xml | 2 +- redisson-hibernate/redisson-hibernate-53/pom.xml | 2 +- redisson-hibernate/redisson-hibernate-6/pom.xml | 2 +- redisson-micronaut/pom.xml | 2 +- redisson-micronaut/redisson-micronaut-20/pom.xml | 2 +- redisson-micronaut/redisson-micronaut-30/pom.xml | 2 +- redisson-mybatis/pom.xml | 2 +- redisson-quarkus/pom.xml | 2 +- redisson-quarkus/redisson-quarkus-16/deployment/pom.xml | 2 +- .../redisson-quarkus-16/integration-tests/pom.xml | 2 +- redisson-quarkus/redisson-quarkus-16/pom.xml | 2 +- redisson-quarkus/redisson-quarkus-16/runtime/pom.xml | 2 +- redisson-quarkus/redisson-quarkus-20/deployment/pom.xml | 2 +- .../redisson-quarkus-20/integration-tests/pom.xml | 2 +- redisson-quarkus/redisson-quarkus-20/pom.xml | 2 +- redisson-quarkus/redisson-quarkus-20/runtime/pom.xml | 2 +- redisson-spring-boot-starter/pom.xml | 2 +- redisson-spring-data/pom.xml | 2 +- redisson-spring-data/redisson-spring-data-16/pom.xml | 2 +- redisson-spring-data/redisson-spring-data-17/pom.xml | 2 +- redisson-spring-data/redisson-spring-data-18/pom.xml | 2 +- redisson-spring-data/redisson-spring-data-20/pom.xml | 2 +- redisson-spring-data/redisson-spring-data-21/pom.xml | 2 +- redisson-spring-data/redisson-spring-data-22/pom.xml | 2 +- redisson-spring-data/redisson-spring-data-23/pom.xml | 2 +- redisson-spring-data/redisson-spring-data-24/pom.xml | 2 +- redisson-spring-data/redisson-spring-data-25/pom.xml | 2 +- redisson-spring-data/redisson-spring-data-26/pom.xml | 2 +- redisson-spring-data/redisson-spring-data-27/pom.xml | 2 +- redisson-spring-data/redisson-spring-data-30/pom.xml | 2 +- redisson-tomcat/pom.xml | 2 +- redisson-tomcat/redisson-tomcat-10/pom.xml | 2 +- redisson-tomcat/redisson-tomcat-7/pom.xml | 2 +- redisson-tomcat/redisson-tomcat-8/pom.xml | 2 +- redisson-tomcat/redisson-tomcat-9/pom.xml | 2 +- redisson/pom.xml | 2 +- 44 files changed, 46 insertions(+), 46 deletions(-) diff --git a/pom.xml b/pom.xml index a84ecbf69..2c804dfe2 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ org.redisson redisson-parent - 3.19.0 + 3.19.1-SNAPSHOT pom Redisson @@ -29,7 +29,7 @@ scm:git:git@github.com:redisson/redisson.git scm:git:git@github.com:redisson/redisson.git scm:git:git@github.com:redisson/redisson.git - redisson-3.19.0 + HEAD diff --git a/redisson-all/pom.xml b/redisson-all/pom.xml index ec0d5d697..21d25eb62 100644 --- a/redisson-all/pom.xml +++ b/redisson-all/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-parent - 3.19.0 + 3.19.1-SNAPSHOT ../ @@ -26,7 +26,7 @@ scm:git:git@github.com:mrniko/redisson.git scm:git:git@github.com:mrniko/redisson.git scm:git:git@github.com:mrniko/redisson.git - redisson-3.19.0 + redisson-parent-0.9.0 diff --git a/redisson-helidon/pom.xml b/redisson-helidon/pom.xml index 5f1ad9ef9..d86c05d2c 100644 --- a/redisson-helidon/pom.xml +++ b/redisson-helidon/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-parent - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-helidon/redisson-helidon-20/pom.xml b/redisson-helidon/redisson-helidon-20/pom.xml index aa8961d3d..05d4d1a7a 100644 --- a/redisson-helidon/redisson-helidon-20/pom.xml +++ b/redisson-helidon/redisson-helidon-20/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-helidon - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-helidon/redisson-helidon-30/pom.xml b/redisson-helidon/redisson-helidon-30/pom.xml index adc4af9a2..da7adb895 100644 --- a/redisson-helidon/redisson-helidon-30/pom.xml +++ b/redisson-helidon/redisson-helidon-30/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-helidon - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-hibernate/pom.xml b/redisson-hibernate/pom.xml index 7de17eb34..3172b13b2 100644 --- a/redisson-hibernate/pom.xml +++ b/redisson-hibernate/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-parent - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-hibernate/redisson-hibernate-4/pom.xml b/redisson-hibernate/redisson-hibernate-4/pom.xml index 9dd4d8325..f3977aa29 100644 --- a/redisson-hibernate/redisson-hibernate-4/pom.xml +++ b/redisson-hibernate/redisson-hibernate-4/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-hibernate - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-hibernate/redisson-hibernate-5/pom.xml b/redisson-hibernate/redisson-hibernate-5/pom.xml index 3abfa74e7..68ee132bc 100644 --- a/redisson-hibernate/redisson-hibernate-5/pom.xml +++ b/redisson-hibernate/redisson-hibernate-5/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-hibernate - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-hibernate/redisson-hibernate-52/pom.xml b/redisson-hibernate/redisson-hibernate-52/pom.xml index 1843abd73..1c1754005 100644 --- a/redisson-hibernate/redisson-hibernate-52/pom.xml +++ b/redisson-hibernate/redisson-hibernate-52/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-hibernate - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-hibernate/redisson-hibernate-53/pom.xml b/redisson-hibernate/redisson-hibernate-53/pom.xml index 91167a596..dc7a83f21 100644 --- a/redisson-hibernate/redisson-hibernate-53/pom.xml +++ b/redisson-hibernate/redisson-hibernate-53/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-hibernate - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-hibernate/redisson-hibernate-6/pom.xml b/redisson-hibernate/redisson-hibernate-6/pom.xml index 6d4506527..74b3dd658 100644 --- a/redisson-hibernate/redisson-hibernate-6/pom.xml +++ b/redisson-hibernate/redisson-hibernate-6/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-hibernate - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-micronaut/pom.xml b/redisson-micronaut/pom.xml index eccde3b4e..4ac28524f 100644 --- a/redisson-micronaut/pom.xml +++ b/redisson-micronaut/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-parent - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-micronaut/redisson-micronaut-20/pom.xml b/redisson-micronaut/redisson-micronaut-20/pom.xml index 14ae5fba4..f786cabfe 100644 --- a/redisson-micronaut/redisson-micronaut-20/pom.xml +++ b/redisson-micronaut/redisson-micronaut-20/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-micronaut - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-micronaut/redisson-micronaut-30/pom.xml b/redisson-micronaut/redisson-micronaut-30/pom.xml index 60274ee63..19aa6af2c 100644 --- a/redisson-micronaut/redisson-micronaut-30/pom.xml +++ b/redisson-micronaut/redisson-micronaut-30/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-micronaut - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-mybatis/pom.xml b/redisson-mybatis/pom.xml index f6642f073..a1c6a86e4 100644 --- a/redisson-mybatis/pom.xml +++ b/redisson-mybatis/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-parent - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-quarkus/pom.xml b/redisson-quarkus/pom.xml index da45704be..59f2cfa66 100644 --- a/redisson-quarkus/pom.xml +++ b/redisson-quarkus/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-parent - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-quarkus/redisson-quarkus-16/deployment/pom.xml b/redisson-quarkus/redisson-quarkus-16/deployment/pom.xml index 0a7205c6a..e643ad164 100644 --- a/redisson-quarkus/redisson-quarkus-16/deployment/pom.xml +++ b/redisson-quarkus/redisson-quarkus-16/deployment/pom.xml @@ -5,7 +5,7 @@ org.redisson redisson-quarkus-16-parent - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-quarkus/redisson-quarkus-16/integration-tests/pom.xml b/redisson-quarkus/redisson-quarkus-16/integration-tests/pom.xml index 624e34d90..b38fdfb71 100644 --- a/redisson-quarkus/redisson-quarkus-16/integration-tests/pom.xml +++ b/redisson-quarkus/redisson-quarkus-16/integration-tests/pom.xml @@ -5,7 +5,7 @@ org.redisson redisson-quarkus-16-parent - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-quarkus/redisson-quarkus-16/pom.xml b/redisson-quarkus/redisson-quarkus-16/pom.xml index 21bb0b438..1f907d8ca 100644 --- a/redisson-quarkus/redisson-quarkus-16/pom.xml +++ b/redisson-quarkus/redisson-quarkus-16/pom.xml @@ -21,7 +21,7 @@ org.redisson redisson-quarkus - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-quarkus/redisson-quarkus-16/runtime/pom.xml b/redisson-quarkus/redisson-quarkus-16/runtime/pom.xml index 3086bed3e..9ee0c7028 100644 --- a/redisson-quarkus/redisson-quarkus-16/runtime/pom.xml +++ b/redisson-quarkus/redisson-quarkus-16/runtime/pom.xml @@ -5,7 +5,7 @@ org.redisson redisson-quarkus-16-parent - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-quarkus/redisson-quarkus-20/deployment/pom.xml b/redisson-quarkus/redisson-quarkus-20/deployment/pom.xml index d283c021a..e93e43ee1 100644 --- a/redisson-quarkus/redisson-quarkus-20/deployment/pom.xml +++ b/redisson-quarkus/redisson-quarkus-20/deployment/pom.xml @@ -5,7 +5,7 @@ org.redisson redisson-quarkus-20-parent - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-quarkus/redisson-quarkus-20/integration-tests/pom.xml b/redisson-quarkus/redisson-quarkus-20/integration-tests/pom.xml index c358734b2..f3ec51e18 100644 --- a/redisson-quarkus/redisson-quarkus-20/integration-tests/pom.xml +++ b/redisson-quarkus/redisson-quarkus-20/integration-tests/pom.xml @@ -5,7 +5,7 @@ org.redisson redisson-quarkus-20-parent - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-quarkus/redisson-quarkus-20/pom.xml b/redisson-quarkus/redisson-quarkus-20/pom.xml index 0562d4b3e..3fee44378 100644 --- a/redisson-quarkus/redisson-quarkus-20/pom.xml +++ b/redisson-quarkus/redisson-quarkus-20/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-quarkus - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-quarkus/redisson-quarkus-20/runtime/pom.xml b/redisson-quarkus/redisson-quarkus-20/runtime/pom.xml index e1fff96ba..e2b8e4659 100644 --- a/redisson-quarkus/redisson-quarkus-20/runtime/pom.xml +++ b/redisson-quarkus/redisson-quarkus-20/runtime/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-quarkus-20-parent - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-spring-boot-starter/pom.xml b/redisson-spring-boot-starter/pom.xml index d49ce5f38..958ec9546 100644 --- a/redisson-spring-boot-starter/pom.xml +++ b/redisson-spring-boot-starter/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-parent - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-spring-data/pom.xml b/redisson-spring-data/pom.xml index b10956f91..284d3050a 100644 --- a/redisson-spring-data/pom.xml +++ b/redisson-spring-data/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-parent - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-spring-data/redisson-spring-data-16/pom.xml b/redisson-spring-data/redisson-spring-data-16/pom.xml index baa161550..54b2cd91e 100644 --- a/redisson-spring-data/redisson-spring-data-16/pom.xml +++ b/redisson-spring-data/redisson-spring-data-16/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-spring-data - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-spring-data/redisson-spring-data-17/pom.xml b/redisson-spring-data/redisson-spring-data-17/pom.xml index 54cd5210a..a2c97d04d 100644 --- a/redisson-spring-data/redisson-spring-data-17/pom.xml +++ b/redisson-spring-data/redisson-spring-data-17/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-spring-data - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-spring-data/redisson-spring-data-18/pom.xml b/redisson-spring-data/redisson-spring-data-18/pom.xml index bd471418f..3395d1fda 100644 --- a/redisson-spring-data/redisson-spring-data-18/pom.xml +++ b/redisson-spring-data/redisson-spring-data-18/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-spring-data - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-spring-data/redisson-spring-data-20/pom.xml b/redisson-spring-data/redisson-spring-data-20/pom.xml index 8b32b4a17..d674a0cbe 100644 --- a/redisson-spring-data/redisson-spring-data-20/pom.xml +++ b/redisson-spring-data/redisson-spring-data-20/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-spring-data - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-spring-data/redisson-spring-data-21/pom.xml b/redisson-spring-data/redisson-spring-data-21/pom.xml index 5ce9e3a1b..0897d639c 100644 --- a/redisson-spring-data/redisson-spring-data-21/pom.xml +++ b/redisson-spring-data/redisson-spring-data-21/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-spring-data - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-spring-data/redisson-spring-data-22/pom.xml b/redisson-spring-data/redisson-spring-data-22/pom.xml index 44e3448c7..af501e01d 100644 --- a/redisson-spring-data/redisson-spring-data-22/pom.xml +++ b/redisson-spring-data/redisson-spring-data-22/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-spring-data - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-spring-data/redisson-spring-data-23/pom.xml b/redisson-spring-data/redisson-spring-data-23/pom.xml index 0601e75bd..89bb6acad 100644 --- a/redisson-spring-data/redisson-spring-data-23/pom.xml +++ b/redisson-spring-data/redisson-spring-data-23/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-spring-data - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-spring-data/redisson-spring-data-24/pom.xml b/redisson-spring-data/redisson-spring-data-24/pom.xml index 35c19e3f8..357bf6943 100644 --- a/redisson-spring-data/redisson-spring-data-24/pom.xml +++ b/redisson-spring-data/redisson-spring-data-24/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-spring-data - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-spring-data/redisson-spring-data-25/pom.xml b/redisson-spring-data/redisson-spring-data-25/pom.xml index 81483832e..1e7ac983e 100644 --- a/redisson-spring-data/redisson-spring-data-25/pom.xml +++ b/redisson-spring-data/redisson-spring-data-25/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-spring-data - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-spring-data/redisson-spring-data-26/pom.xml b/redisson-spring-data/redisson-spring-data-26/pom.xml index bf268d840..444172b9d 100644 --- a/redisson-spring-data/redisson-spring-data-26/pom.xml +++ b/redisson-spring-data/redisson-spring-data-26/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-spring-data - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-spring-data/redisson-spring-data-27/pom.xml b/redisson-spring-data/redisson-spring-data-27/pom.xml index 685fa5fff..0513bfe4f 100644 --- a/redisson-spring-data/redisson-spring-data-27/pom.xml +++ b/redisson-spring-data/redisson-spring-data-27/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-spring-data - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-spring-data/redisson-spring-data-30/pom.xml b/redisson-spring-data/redisson-spring-data-30/pom.xml index a54c45463..7f31535cb 100644 --- a/redisson-spring-data/redisson-spring-data-30/pom.xml +++ b/redisson-spring-data/redisson-spring-data-30/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-spring-data - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-tomcat/pom.xml b/redisson-tomcat/pom.xml index 09b183f30..d3a24338c 100644 --- a/redisson-tomcat/pom.xml +++ b/redisson-tomcat/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-parent - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-tomcat/redisson-tomcat-10/pom.xml b/redisson-tomcat/redisson-tomcat-10/pom.xml index 6d2e7514b..f6bb9c60a 100644 --- a/redisson-tomcat/redisson-tomcat-10/pom.xml +++ b/redisson-tomcat/redisson-tomcat-10/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-tomcat - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-tomcat/redisson-tomcat-7/pom.xml b/redisson-tomcat/redisson-tomcat-7/pom.xml index 04e217618..065110ceb 100644 --- a/redisson-tomcat/redisson-tomcat-7/pom.xml +++ b/redisson-tomcat/redisson-tomcat-7/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-tomcat - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-tomcat/redisson-tomcat-8/pom.xml b/redisson-tomcat/redisson-tomcat-8/pom.xml index d98abf31f..753759378 100644 --- a/redisson-tomcat/redisson-tomcat-8/pom.xml +++ b/redisson-tomcat/redisson-tomcat-8/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-tomcat - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson-tomcat/redisson-tomcat-9/pom.xml b/redisson-tomcat/redisson-tomcat-9/pom.xml index 7acfc677c..4623e9733 100644 --- a/redisson-tomcat/redisson-tomcat-9/pom.xml +++ b/redisson-tomcat/redisson-tomcat-9/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-tomcat - 3.19.0 + 3.19.1-SNAPSHOT ../ diff --git a/redisson/pom.xml b/redisson/pom.xml index 591a23b94..de0ef5b96 100644 --- a/redisson/pom.xml +++ b/redisson/pom.xml @@ -4,7 +4,7 @@ org.redisson redisson-parent - 3.19.0 + 3.19.1-SNAPSHOT ../ From ae0ad52df6d4f47a71a2c67abdb5739f867a8964 Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Fri, 16 Dec 2022 12:34:51 +0300 Subject: [PATCH 34/58] Update CHANGELOG.md --- CHANGELOG.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a21f95ace..64272105a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,29 @@ Redisson Releases History Try __[Redisson PRO](https://redisson.pro)__ with **ultra-fast performance** and **support by SLA**. +### 16-Dec-2022 - 3.19.0 released + +Feature - implementation of Spring Cache methods added in Spring 5.2 +Feature - `entriesRead` and `lag` fields added to `StreamGroup` object +Feature - added [RFencedLock](https://github.com/redisson/redisson/wiki/8.-distributed-locks-and-synchronizers/#810-fenced-lock) implementation +Feature - [credentialsResolver](https://github.com/redisson/redisson/wiki/2.-Configuration#credentialsresolver) setting added + +__Breaking change - default codec changed to Kryo5Codec__ + +Fixed - new Redis node isn't discovered between PubSub subscription attempts +Fixed - `codec`,`nettyHook`,`addressResolverGroupFactory`,`connectionListener` settings can't be defined through Micronaut config +Fixed - evictions metrics doesn't work for RedissonCache (thanks @Nicola Dardanis) +Fixed - PubSub connection isn't reused if it reached subscriptions limit before unsubscribe operation +Fixed - PubSub connection returns to connection pool only if subscriptions limit was reached +Fixed - use slf4j late-binding when logging instead of string concat (thanks @vatarasov) +Fixed - most of pubsub subscriptions fail to resubscribe after failover +Fixed - `RBatch` with `executionMode = REDIS_WRITE_ATOMIC` throws NPE in case of connection starvation +Fixed - `CommandDecoder.messageDecoder()` method throws NPE if `RBatch` object used with `executionMode = IN_MEMORY` (regression since 3.18.1) +Fixed - some scheduled tasks aren't executed (regression since 3.17.5) +Fixed - `RFunction` doesn't pass keys to Redis correctly (thanks @@jordanrmerrick) +Fixed - incorrectly reset jackson type factory (thanks @noelvo) +Fixed - cluster partitions parsing error isn't logged + ### 30-Nov-2022 - 3.18.1 released Feature - Spring Data Redis 3.0.0 module added From 9fa0ff44b8c7d48e299c24e813a09322b564bc82 Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Fri, 16 Dec 2022 13:29:47 +0300 Subject: [PATCH 35/58] version updated --- README.md | 10 +++++----- redisson-helidon/README.md | 6 +++--- redisson-hibernate/README.md | 12 ++++++------ redisson-micronaut/README.md | 6 +++--- redisson-mybatis/README.md | 4 ++-- redisson-quarkus/README.md | 6 +++--- redisson-spring-boot-starter/README.md | 4 ++-- redisson-spring-data/README.md | 26 +++++++++++++------------- redisson-tomcat/README.md | 10 +++++----- 9 files changed, 42 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index f61865193..d02ee8fb8 100644 --- a/README.md +++ b/README.md @@ -106,14 +106,14 @@ Used by org.redisson redisson - 3.18.1 + 3.19.0 #### Gradle - compile 'org.redisson:redisson:3.18.1' + compile 'org.redisson:redisson:3.19.0' #### SBT - libraryDependencies += "org.redisson" % "redisson" % "3.18.1" + libraryDependencies += "org.redisson" % "redisson" % "3.19.0" #### Java @@ -171,8 +171,8 @@ Try __[Redisson PRO](https://redisson.pro)__ with **ultra-fast performance** and ## Downloads -[Redisson 3.18.1](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson&v=3.18.1&e=jar), -[Redisson node 3.18.1](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-all&v=3.18.1&e=jar) +[Redisson 3.19.0](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson&v=3.19.0&e=jar), +[Redisson node 3.19.0](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-all&v=3.19.0&e=jar) ## FAQs diff --git a/redisson-helidon/README.md b/redisson-helidon/README.md index 7dc843024..32914b2b8 100644 --- a/redisson-helidon/README.md +++ b/redisson-helidon/README.md @@ -17,7 +17,7 @@ Maven redisson-helidon-20 redisson-helidon-30 - 3.18.1 + 3.19.0 ``` @@ -25,9 +25,9 @@ Gradle ```groovy // for Helidon v1.4.x - v2.5.x -compile 'org.redisson:redisson-helidon-20:3.18.1' +compile 'org.redisson:redisson-helidon-20:3.19.0' // for Helidon v3.0.x -compile 'org.redisson:redisson-helidon-30:3.18.1' +compile 'org.redisson:redisson-helidon-30:3.19.0' ``` ### 2. Add settings into `META-INF/microprofile-config.properties` file diff --git a/redisson-hibernate/README.md b/redisson-hibernate/README.md index 764a55481..b465e30d5 100644 --- a/redisson-hibernate/README.md +++ b/redisson-hibernate/README.md @@ -40,7 +40,7 @@ Maven redisson-hibernate-53 redisson-hibernate-6 - 3.18.1 + 3.19.0 ``` @@ -48,15 +48,15 @@ Gradle ```groovy // for Hibernate v4.x - compile 'org.redisson:redisson-hibernate-4:3.18.1' + compile 'org.redisson:redisson-hibernate-4:3.19.0' // for Hibernate v5.0.x - v5.1.x - compile 'org.redisson:redisson-hibernate-5:3.18.1' + compile 'org.redisson:redisson-hibernate-5:3.19.0' // for Hibernate v5.2.x - compile 'org.redisson:redisson-hibernate-52:3.18.1' + compile 'org.redisson:redisson-hibernate-52:3.19.0' // for Hibernate v5.3.3+ - v5.6.x - compile 'org.redisson:redisson-hibernate-53:3.18.1' + compile 'org.redisson:redisson-hibernate-53:3.19.0' // for Hibernate v6.0.2+ - v6.1.x - compile 'org.redisson:redisson-hibernate-6:3.18.1' + compile 'org.redisson:redisson-hibernate-6:3.19.0' ``` ### 2. Specify hibernate cache settings diff --git a/redisson-micronaut/README.md b/redisson-micronaut/README.md index 521ebd3e6..a2f8455ce 100644 --- a/redisson-micronaut/README.md +++ b/redisson-micronaut/README.md @@ -17,7 +17,7 @@ Maven redisson-micronaut-20 redisson-micronaut-30 - 3.18.1 + 3.19.0 ``` @@ -25,9 +25,9 @@ Gradle ```groovy // for Micronaut v2.0.x - v2.5.x -compile 'org.redisson:redisson-micronaut-20:3.18.1' +compile 'org.redisson:redisson-micronaut-20:3.19.0' // for Micronaut v3.x.x -compile 'org.redisson:redisson-micronaut-30:3.18.1' +compile 'org.redisson:redisson-micronaut-30:3.19.0' ``` ### 2. Add settings into `application.yml` file diff --git a/redisson-mybatis/README.md b/redisson-mybatis/README.md index f3650841f..74be5dab7 100644 --- a/redisson-mybatis/README.md +++ b/redisson-mybatis/README.md @@ -30,14 +30,14 @@ Maven org.redisson redisson-mybatis - 3.18.1 + 3.19.0 ``` Gradle ```groovy - compile 'org.redisson:redisson-mybatis:3.18.1' + compile 'org.redisson:redisson-mybatis:3.19.0' ``` ### 2. Specify MyBatis cache settings diff --git a/redisson-quarkus/README.md b/redisson-quarkus/README.md index 40512c3dc..d1b735d60 100644 --- a/redisson-quarkus/README.md +++ b/redisson-quarkus/README.md @@ -42,7 +42,7 @@ Maven redisson-quarkus-16 redisson-quarkus-20 - 3.18.1 + 3.19.0 ``` @@ -50,9 +50,9 @@ Gradle ```groovy // for Quarkus v1.6.x - v1.13.x -compile 'org.redisson:redisson-quarkus-16:3.18.1' +compile 'org.redisson:redisson-quarkus-16:3.19.0' // for Quarkus v2.x.x -compile 'org.redisson:redisson-quarkus-20:3.18.1' +compile 'org.redisson:redisson-quarkus-20:3.19.0' ``` ### 2. Add settings into `application.properties` file diff --git a/redisson-spring-boot-starter/README.md b/redisson-spring-boot-starter/README.md index 3a96e7471..043784ec3 100644 --- a/redisson-spring-boot-starter/README.md +++ b/redisson-spring-boot-starter/README.md @@ -14,14 +14,14 @@ Maven org.redisson redisson-spring-boot-starter - 3.18.1 + 3.19.0 ``` Gradle ```groovy - compile 'org.redisson:redisson-spring-boot-starter:3.18.1' + compile 'org.redisson:redisson-spring-boot-starter:3.19.0' ``` diff --git a/redisson-spring-data/README.md b/redisson-spring-data/README.md index bdfff4cc6..a1011584b 100644 --- a/redisson-spring-data/README.md +++ b/redisson-spring-data/README.md @@ -35,7 +35,7 @@ Maven redisson-spring-data-27 redisson-spring-data-30 - 3.18.1 + 3.19.0 ``` @@ -43,29 +43,29 @@ Gradle ```groovy // for Spring Data Redis v.1.6.x - compile 'org.redisson:redisson-spring-data-16:3.18.1' + compile 'org.redisson:redisson-spring-data-16:3.19.0' // for Spring Data Redis v.1.7.x - compile 'org.redisson:redisson-spring-data-17:3.18.1' + compile 'org.redisson:redisson-spring-data-17:3.19.0' // for Spring Data Redis v.1.8.x - compile 'org.redisson:redisson-spring-data-18:3.18.1' + compile 'org.redisson:redisson-spring-data-18:3.19.0' // for Spring Data Redis v.2.0.x - compile 'org.redisson:redisson-spring-data-20:3.18.1' + compile 'org.redisson:redisson-spring-data-20:3.19.0' // for Spring Data Redis v.2.1.x - compile 'org.redisson:redisson-spring-data-21:3.18.1' + compile 'org.redisson:redisson-spring-data-21:3.19.0' // for Spring Data Redis v.2.2.x - compile 'org.redisson:redisson-spring-data-22:3.18.1' + compile 'org.redisson:redisson-spring-data-22:3.19.0' // for Spring Data Redis v.2.3.x - compile 'org.redisson:redisson-spring-data-23:3.18.1' + compile 'org.redisson:redisson-spring-data-23:3.19.0' // for Spring Data Redis v.2.4.x - compile 'org.redisson:redisson-spring-data-24:3.18.1' + compile 'org.redisson:redisson-spring-data-24:3.19.0' // for Spring Data Redis v.2.5.x - compile 'org.redisson:redisson-spring-data-25:3.18.1' + compile 'org.redisson:redisson-spring-data-25:3.19.0' // for Spring Data Redis v.2.6.x - compile 'org.redisson:redisson-spring-data-26:3.18.1' + compile 'org.redisson:redisson-spring-data-26:3.19.0' // for Spring Data Redis v.2.7.x - compile 'org.redisson:redisson-spring-data-27:3.18.1' + compile 'org.redisson:redisson-spring-data-27:3.19.0' // for Spring Data Redis v.3.0.x - compile 'org.redisson:redisson-spring-data-30:3.18.1' + compile 'org.redisson:redisson-spring-data-30:3.19.0' ``` ### 2. Register `RedissonConnectionFactory` in Spring context diff --git a/redisson-tomcat/README.md b/redisson-tomcat/README.md index 095117d18..6a41f0a24 100644 --- a/redisson-tomcat/README.md +++ b/redisson-tomcat/README.md @@ -67,14 +67,14 @@ Amount of Redisson instances created by Tomcat for multiple contexts could be re ### 2. Copy two jars into `TOMCAT_BASE/lib` directory: -[redisson-all-3.18.1.jar](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-all&v=3.18.1&e=jar) +[redisson-all-3.19.0.jar](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-all&v=3.19.0&e=jar) -Tomcat 7.x - [redisson-tomcat-7-3.18.1.jar](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-tomcat-7&v=3.18.1&e=jar) +Tomcat 7.x - [redisson-tomcat-7-3.19.0.jar](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-tomcat-7&v=3.19.0&e=jar) -Tomcat 8.x - [redisson-tomcat-8-3.18.1.jar](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-tomcat-8&v=3.18.1&e=jar) +Tomcat 8.x - [redisson-tomcat-8-3.19.0.jar](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-tomcat-8&v=3.19.0&e=jar) -Tomcat 9.x - [redisson-tomcat-9-3.18.1.jar](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-tomcat-9&v=3.18.1&e=jar) +Tomcat 9.x - [redisson-tomcat-9-3.19.0.jar](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-tomcat-9&v=3.19.0&e=jar) -Tomcat 10.x - [redisson-tomcat-10-3.18.1.jar](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-tomcat-10&v=3.18.1&e=jar) +Tomcat 10.x - [redisson-tomcat-10-3.19.0.jar](https://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=org.redisson&a=redisson-tomcat-10&v=3.19.0&e=jar) Try __[Redisson PRO](https://redisson.pro)__ with **ultra-fast performance** and **support by SLA**. From 3b79c36529cc65c5fd6a19b01a578af0d8051fd6 Mon Sep 17 00:00:00 2001 From: Javed Date: Sun, 18 Dec 2022 11:55:04 +0800 Subject: [PATCH 36/58] Fixed - BloomFilter createBitSet method Signed-off-by: Javed --- redisson/src/main/java/org/redisson/RedissonBloomFilter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redisson/src/main/java/org/redisson/RedissonBloomFilter.java b/redisson/src/main/java/org/redisson/RedissonBloomFilter.java index 86cf0401c..039911dd7 100644 --- a/redisson/src/main/java/org/redisson/RedissonBloomFilter.java +++ b/redisson/src/main/java/org/redisson/RedissonBloomFilter.java @@ -187,7 +187,7 @@ public class RedissonBloomFilter extends RedissonExpirable implements RBloomF } protected RBitSetAsync createBitSet(CommandBatchService executorService) { - return new RedissonBitSet(executorService, getRawName()); + return new RedissonBitSet(executorService, getName()); } private void addConfigCheck(int hashIterations, long size, CommandBatchService executorService) { From d9ed24348649a89f223b3c422f89de060780131c Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Sun, 18 Dec 2022 12:00:13 +0300 Subject: [PATCH 37/58] Update README.md --- README.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index d02ee8fb8..1b37fb7b4 100644 --- a/README.md +++ b/README.md @@ -7,15 +7,12 @@ Based on high-performance async and lock-free Java Redis client and [Netty](http://netty.io) framework. Supported JDK: 1.8 ... 19 and Android -Supported Redis: 3.0 ... 7.0 +Supported Redis: 3.0 ... 7.0 +Compatible with [AWS ElastiCache](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/WhatIs.html), [Amazon MemoryDB](https://aws.amazon.com/memorydb), [Azure Redis Cache](https://azure.microsoft.com/en-us/services/cache/), [Google Cloud Memorystore for Redis](https://cloud.google.com/memorystore/docs/redis/), [Redis Enterprise](https://redis.com/redis-enterprise/) ## Features -* Redis Replicated setup (also compatible with [AWS ElastiCache](http://docs.aws.amazon.com/AmazonElastiCache/latest/UserGuide/Replication.html) and [Azure Redis Cache](https://azure.microsoft.com/en-us/services/cache/)) -* Redis Cluster setup (also compatible with [AWS ElastiCache Cluster](http://docs.aws.amazon.com/AmazonElastiCache/latest/UserGuide/Clusters.html), [Amazon MemoryDB](https://aws.amazon.com/memorydb) and [Azure Redis Cache](https://azure.microsoft.com/en-us/services/cache/)) -* Redis Sentinel setup -* Redis with Master with Slave only -* Redis Single (also compatible with [Azure Redis Cache](https://azure.microsoft.com/en-us/services/cache/) and [Google Cloud Memorystore for Redis](https://cloud.google.com/memorystore/docs/redis/)) +* Supports [Redis Replicated](https://github.com/redisson/redisson/wiki/2.-Configuration/#25-replicated-mode), [Redis Cluster](https://github.com/redisson/redisson/wiki/2.-Configuration/#24-cluster-mode), [Redis Sentinel](https://github.com/redisson/redisson/wiki/2.-Configuration/#27-sentinel-mode), [Redis Master and Slaves](https://github.com/redisson/redisson/wiki/2.-Configuration/#28-master-slave-mode), [Redis Single](https://github.com/redisson/redisson/wiki/2.-Configuration/#26-single-instance-mode) setup * Thread-safe implementation * [JSON datatype](https://github.com/redisson/redisson/wiki/6.-distributed-objects/#615-json-object-holder) * [Reactive Streams](https://github.com/redisson/redisson/wiki/3.-operations-execution#32-reactive-way) API From b0ded686e738e862023ccd1fcdc1ec2991f34635 Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Sun, 18 Dec 2022 12:03:56 +0300 Subject: [PATCH 38/58] Update README.md --- README.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 1b37fb7b4..6c99e759f 100644 --- a/README.md +++ b/README.md @@ -8,18 +8,22 @@ Based on high-performance async and lock-free Java Redis client and [Netty](http://netty.io) framework. Supported JDK: 1.8 ... 19 and Android Supported Redis: 3.0 ... 7.0 -Compatible with [AWS ElastiCache](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/WhatIs.html), [Amazon MemoryDB](https://aws.amazon.com/memorydb), [Azure Redis Cache](https://azure.microsoft.com/en-us/services/cache/), [Google Cloud Memorystore for Redis](https://cloud.google.com/memorystore/docs/redis/), [Redis Enterprise](https://redis.com/redis-enterprise/) ## Features -* Supports [Redis Replicated](https://github.com/redisson/redisson/wiki/2.-Configuration/#25-replicated-mode), [Redis Cluster](https://github.com/redisson/redisson/wiki/2.-Configuration/#24-cluster-mode), [Redis Sentinel](https://github.com/redisson/redisson/wiki/2.-Configuration/#27-sentinel-mode), [Redis Master and Slaves](https://github.com/redisson/redisson/wiki/2.-Configuration/#28-master-slave-mode), [Redis Single](https://github.com/redisson/redisson/wiki/2.-Configuration/#26-single-instance-mode) setup * Thread-safe implementation +* Supports [Redis Replicated](https://github.com/redisson/redisson/wiki/2.-Configuration/#25-replicated-mode), [Redis Cluster](https://github.com/redisson/redisson/wiki/2.-Configuration/#24-cluster-mode), [Redis Sentinel](https://github.com/redisson/redisson/wiki/2.-Configuration/#27-sentinel-mode), [Redis Master and Slaves](https://github.com/redisson/redisson/wiki/2.-Configuration/#28-master-slave-mode), [Redis Single](https://github.com/redisson/redisson/wiki/2.-Configuration/#26-single-instance-mode) setup +* Supports [AWS ElastiCache](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/WhatIs.html), [Amazon MemoryDB](https://aws.amazon.com/memorydb), [Azure Redis Cache](https://azure.microsoft.com/en-us/services/cache/), [Google Cloud Memorystore for Redis](https://cloud.google.com/memorystore/docs/redis/), [Redis Enterprise](https://redis.com/redis-enterprise/) +* Supports auto-reconnection +* Supports failed to send command auto-retry +* Supports OSGi +* Supports SSL +* Asynchronous connection pool +* Lua scripting * [JSON datatype](https://github.com/redisson/redisson/wiki/6.-distributed-objects/#615-json-object-holder) * [Reactive Streams](https://github.com/redisson/redisson/wiki/3.-operations-execution#32-reactive-way) API * [RxJava3](https://github.com/redisson/redisson/wiki/3.-operations-execution#32-reactive-way) API * [Asynchronous](https://github.com/redisson/redisson/wiki/3.-operations-execution#31-async-way) API -* Asynchronous connection pool -* Lua scripting * Local cache support including [Caffeine](https://github.com/ben-manes/caffeine)-based implementation * [Distributed Java objects](https://github.com/redisson/redisson/wiki/6.-Distributed-objects) Object holder, Binary stream holder, Geospatial holder, BitSet, AtomicLong, AtomicDouble, PublishSubscribe, @@ -44,13 +48,8 @@ Compatible with [AWS ElastiCache](https://docs.aws.amazon.com/AmazonElastiCache/ * [Tomcat Session Manager](https://github.com/redisson/redisson/tree/master/redisson-tomcat) implementation * [Spring Session](https://github.com/redisson/redisson/wiki/14.-Integration-with-frameworks/#147-spring-session) implementation * [Redis pipelining](https://github.com/redisson/redisson/wiki/10.-additional-features#103-execution-batches-of-commands) (command batches) -* Supports Android platform -* Supports auto-reconnection -* Supports failed to send command auto-retry -* Supports OSGi -* Supports SSL * Supports many popular codecs ([JBoss Marshalling](https://github.com/jboss-remoting/jboss-marshalling), [Jackson JSON](https://github.com/FasterXML/jackson), [Avro](http://avro.apache.org/), [Smile](http://wiki.fasterxml.com/SmileFormatSpec), [CBOR](http://cbor.io/), [MsgPack](http://msgpack.org/), [Kryo](https://github.com/EsotericSoftware/kryo), [Amazon Ion](https://amzn.github.io/ion-docs/), [LZ4](https://github.com/jpountz/lz4-java), [Snappy](https://github.com/xerial/snappy-java) and JDK Serialization) -* With over 2000 unit tests +* Over 1800 unit tests + + + + + %d{yyyy.MM.dd HH:mm:ss.SSS} %-5level %c{0} : %msg%n + + + + + + + + + + + + + + + + + From 7e539dbbc03eaa01fbc5021ebf4252f68f613c36 Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Tue, 20 Dec 2022 09:52:41 +0300 Subject: [PATCH 45/58] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6c99e759f..1cd47b797 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Supported Redis: 3.0 ... 7.0 * Thread-safe implementation * Supports [Redis Replicated](https://github.com/redisson/redisson/wiki/2.-Configuration/#25-replicated-mode), [Redis Cluster](https://github.com/redisson/redisson/wiki/2.-Configuration/#24-cluster-mode), [Redis Sentinel](https://github.com/redisson/redisson/wiki/2.-Configuration/#27-sentinel-mode), [Redis Master and Slaves](https://github.com/redisson/redisson/wiki/2.-Configuration/#28-master-slave-mode), [Redis Single](https://github.com/redisson/redisson/wiki/2.-Configuration/#26-single-instance-mode) setup -* Supports [AWS ElastiCache](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/WhatIs.html), [Amazon MemoryDB](https://aws.amazon.com/memorydb), [Azure Redis Cache](https://azure.microsoft.com/en-us/services/cache/), [Google Cloud Memorystore for Redis](https://cloud.google.com/memorystore/docs/redis/), [Redis Enterprise](https://redis.com/redis-enterprise/) +* Supports [AWS ElastiCache](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/WhatIs.html), [Amazon MemoryDB](https://aws.amazon.com/memorydb), [Azure Redis Cache](https://azure.microsoft.com/en-us/services/cache/), [Google Cloud Memorystore for Redis](https://cloud.google.com/memorystore/docs/redis/), [Redis Enterprise](https://redis.com/redis-enterprise/), [Aiven for Redis](https://aiven.io/redis) * Supports auto-reconnection * Supports failed to send command auto-retry * Supports OSGi From ecf0e0b12618b7291d78afd56cc7ff41c8c4f518 Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Tue, 20 Dec 2022 09:53:37 +0300 Subject: [PATCH 46/58] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1cd47b797..c94006f4e 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Supported Redis: 3.0 ... 7.0 * Thread-safe implementation * Supports [Redis Replicated](https://github.com/redisson/redisson/wiki/2.-Configuration/#25-replicated-mode), [Redis Cluster](https://github.com/redisson/redisson/wiki/2.-Configuration/#24-cluster-mode), [Redis Sentinel](https://github.com/redisson/redisson/wiki/2.-Configuration/#27-sentinel-mode), [Redis Master and Slaves](https://github.com/redisson/redisson/wiki/2.-Configuration/#28-master-slave-mode), [Redis Single](https://github.com/redisson/redisson/wiki/2.-Configuration/#26-single-instance-mode) setup -* Supports [AWS ElastiCache](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/WhatIs.html), [Amazon MemoryDB](https://aws.amazon.com/memorydb), [Azure Redis Cache](https://azure.microsoft.com/en-us/services/cache/), [Google Cloud Memorystore for Redis](https://cloud.google.com/memorystore/docs/redis/), [Redis Enterprise](https://redis.com/redis-enterprise/), [Aiven for Redis](https://aiven.io/redis) +* Supports [AWS ElastiCache](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/WhatIs.html), [Amazon MemoryDB](https://aws.amazon.com/memorydb), [Azure Redis Cache](https://azure.microsoft.com/en-us/services/cache/), [Google Cloud Memorystore for Redis](https://cloud.google.com/memorystore/docs/redis/), [Redis Enterprise](https://redis.com/redis-enterprise/), [Aiven for Redis](https://aiven.io/redis) * Supports auto-reconnection * Supports failed to send command auto-retry * Supports OSGi From 9a07b934c9f1c6f0b1ab960ee6411a7cc6907782 Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Wed, 21 Dec 2022 09:46:52 +0300 Subject: [PATCH 47/58] Fixed - RSetRx and RSetReactive miss tryAdd method. --- .../src/main/java/org/redisson/api/RSetReactive.java | 10 ++++++++++ redisson/src/main/java/org/redisson/api/RSetRx.java | 9 +++++++++ 2 files changed, 19 insertions(+) diff --git a/redisson/src/main/java/org/redisson/api/RSetReactive.java b/redisson/src/main/java/org/redisson/api/RSetReactive.java index e1cd76a77..83088a09f 100644 --- a/redisson/src/main/java/org/redisson/api/RSetReactive.java +++ b/redisson/src/main/java/org/redisson/api/RSetReactive.java @@ -239,4 +239,14 @@ public interface RSetReactive extends RCollectionReactive, RSortableReacti */ Mono> readIntersection(String... names); + /** + * Tries to add elements only if none of them in set. + * + * @param values - values to add + * @return true if elements successfully added, + * otherwise false. + */ + Mono tryAdd(V... values); + + } diff --git a/redisson/src/main/java/org/redisson/api/RSetRx.java b/redisson/src/main/java/org/redisson/api/RSetRx.java index 5a2d19992..5ce145416 100644 --- a/redisson/src/main/java/org/redisson/api/RSetRx.java +++ b/redisson/src/main/java/org/redisson/api/RSetRx.java @@ -241,4 +241,13 @@ public interface RSetRx extends RCollectionRx, RSortableRx> { */ Single> readIntersection(String... names); + /** + * Tries to add elements only if none of them in set. + * + * @param values - values to add + * @return true if elements successfully added, + * otherwise false. + */ + Single tryAdd(V... values); + } From f3d891d54ea10d8b2c1827f65a206f838f8cae4f Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Wed, 21 Dec 2022 09:49:01 +0300 Subject: [PATCH 48/58] Fixed - RSetCacheRx and RSetCacheReactive miss tryAdd() method. --- .../org/redisson/api/RSetCacheReactive.java | 23 ++++++++++++++++++- .../java/org/redisson/api/RSetCacheRx.java | 23 ++++++++++++++++++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/redisson/src/main/java/org/redisson/api/RSetCacheReactive.java b/redisson/src/main/java/org/redisson/api/RSetCacheReactive.java index 16e6e1cbe..3d9b54113 100644 --- a/redisson/src/main/java/org/redisson/api/RSetCacheReactive.java +++ b/redisson/src/main/java/org/redisson/api/RSetCacheReactive.java @@ -97,5 +97,26 @@ public interface RSetCacheReactive extends RCollectionReactive, RDestroyab * @return values */ Mono> readAll(); - + + /** + * Tries to add elements only if none of them in set. + * + * @param values - values to add + * @return true if elements successfully added, + * otherwise false. + */ + Mono tryAdd(V... values); + + /** + * Tries to add elements only if none of them in set. + * + * @param values - values to add + * @param ttl - time to live for value. + * If 0 then stores infinitely. + * @param unit - time unit + * @return true if elements successfully added, + * otherwise false. + */ + Mono tryAdd(long ttl, TimeUnit unit, V... values); + } diff --git a/redisson/src/main/java/org/redisson/api/RSetCacheRx.java b/redisson/src/main/java/org/redisson/api/RSetCacheRx.java index 812860cbe..ec0bf2572 100644 --- a/redisson/src/main/java/org/redisson/api/RSetCacheRx.java +++ b/redisson/src/main/java/org/redisson/api/RSetCacheRx.java @@ -97,5 +97,26 @@ public interface RSetCacheRx extends RCollectionRx, RDestroyable { * @return values */ Single> readAll(); - + + /** + * Tries to add elements only if none of them in set. + * + * @param values - values to add + * @return true if elements successfully added, + * otherwise false. + */ + Single tryAdd(V... values); + + /** + * Tries to add elements only if none of them in set. + * + * @param values - values to add + * @param ttl - time to live for value. + * If 0 then stores infinitely. + * @param unit - time unit + * @return true if elements successfully added, + * otherwise false. + */ + Single tryAdd(long ttl, TimeUnit unit, V... values); + } From 1f45b65e255c51d689b773db3346c935660b8597 Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Wed, 21 Dec 2022 09:50:19 +0300 Subject: [PATCH 49/58] refactoring --- .../main/java/org/redisson/RedissonSet.java | 19 ++++++++----------- .../client/protocol/RedisCommands.java | 2 +- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/redisson/src/main/java/org/redisson/RedissonSet.java b/redisson/src/main/java/org/redisson/RedissonSet.java index 7e2d822d3..336b2d926 100644 --- a/redisson/src/main/java/org/redisson/RedissonSet.java +++ b/redisson/src/main/java/org/redisson/RedissonSet.java @@ -26,6 +26,7 @@ import org.redisson.mapreduce.RedissonCollectionMapReduce; import org.redisson.misc.CompletableFutureWrapper; import java.util.*; +import java.util.concurrent.CompletionStage; import java.util.stream.Stream; /** @@ -379,7 +380,7 @@ public class RedissonSet extends RedissonExpirable implements RSet, ScanIt return new CompletableFutureWrapper<>(0); } - List args = new ArrayList(c.size() + 1); + List args = new ArrayList<>(c.size() + 1); args.add(getRawName()); encode(args, c); @@ -389,29 +390,25 @@ public class RedissonSet extends RedissonExpirable implements RSet, ScanIt @Override public RFuture> containsEachAsync(Collection c) { if (c.isEmpty()) { - return RedissonPromise.newSucceededFuture(Collections.emptyList()); + return new CompletableFutureWrapper<>(Collections.emptyList()); } - List args = new ArrayList(c.size() + 1); + + List args = new ArrayList<>(c.size() + 1); args.add(getRawName()); encode(args, c); RFuture> future = commandExecutor.readAsync(getRawName(), codec, RedisCommands.SMISMEMBER, args.toArray()); List keysToCheck = new ArrayList<>(c); - RPromise> result = new RedissonPromise<>(); - future.onComplete((res, e) -> { - if (e != null) { - result.tryFailure(e); - return; - } + CompletionStage> f = future.thenApply(res -> { List containedKeys = new ArrayList<>(); for (int i = 0; i < res.size(); i++) { if (res.get(i) == 1) { containedKeys.add(keysToCheck.get(i)); } } - result.trySuccess(containedKeys); + return containedKeys; }); - return result; + return new CompletableFutureWrapper<>(f); } @Override diff --git a/redisson/src/main/java/org/redisson/client/protocol/RedisCommands.java b/redisson/src/main/java/org/redisson/client/protocol/RedisCommands.java index 05af6e306..ada7f0fc2 100644 --- a/redisson/src/main/java/org/redisson/client/protocol/RedisCommands.java +++ b/redisson/src/main/java/org/redisson/client/protocol/RedisCommands.java @@ -215,7 +215,7 @@ public interface RedisCommands { RedisCommand> SUNION = new RedisCommand>("SUNION", new ObjectSetReplayDecoder()); RedisCommand> SDIFF = new RedisCommand>("SDIFF", new ObjectSetReplayDecoder()); RedisCommand> SINTER = new RedisCommand>("SINTER", new ObjectSetReplayDecoder()); - RedisCommand> SMISMEMBER = new RedisCommand>("SMISMEMBER", new ObjectListReplayDecoder()); + RedisCommand> SMISMEMBER = new RedisCommand<>("SMISMEMBER", new ObjectListReplayDecoder()); RedisStrictCommand LPOS = new RedisStrictCommand<>("LPOS"); RedisCommand LSET = new RedisCommand("LSET", new VoidReplayConvertor()); From 38b866927014078c64fed35cdd11fc1d8af07d70 Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Wed, 21 Dec 2022 09:51:11 +0300 Subject: [PATCH 50/58] Implement_new_SMISMEMBER_command --- .../src/main/java/org/redisson/api/RSetReactive.java | 9 +++++++++ redisson/src/main/java/org/redisson/api/RSetRx.java | 10 ++++++++++ 2 files changed, 19 insertions(+) diff --git a/redisson/src/main/java/org/redisson/api/RSetReactive.java b/redisson/src/main/java/org/redisson/api/RSetReactive.java index 83088a09f..bce95510c 100644 --- a/redisson/src/main/java/org/redisson/api/RSetReactive.java +++ b/redisson/src/main/java/org/redisson/api/RSetReactive.java @@ -19,6 +19,7 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import java.util.Collection; +import java.util.List; import java.util.Set; /** @@ -248,5 +249,13 @@ public interface RSetReactive extends RCollectionReactive, RSortableReacti */ Mono tryAdd(V... values); + /** + * Check if each element is contained in the specified collection. + * Returns contained elements. + * + * @param c - collection to check + * @return contained elements + */ + Mono> containsEach(Collection c); } diff --git a/redisson/src/main/java/org/redisson/api/RSetRx.java b/redisson/src/main/java/org/redisson/api/RSetRx.java index 5ce145416..b660bb0bc 100644 --- a/redisson/src/main/java/org/redisson/api/RSetRx.java +++ b/redisson/src/main/java/org/redisson/api/RSetRx.java @@ -16,6 +16,7 @@ package org.redisson.api; import java.util.Collection; +import java.util.List; import java.util.Set; import io.reactivex.rxjava3.core.Flowable; @@ -250,4 +251,13 @@ public interface RSetRx extends RCollectionRx, RSortableRx> { */ Single tryAdd(V... values); + /** + * Check if each element is contained in the specified collection. + * Returns contained elements. + * + * @param c - collection to check + * @return contained elements + */ + Single> containsEach(Collection c); + } From 541fba21f456fb484319c65028953af169d0b3fe Mon Sep 17 00:00:00 2001 From: Alexander Tulyakov Date: Fri, 16 Dec 2022 18:16:04 +0300 Subject: [PATCH 51/58] Fixed - SharedPubSub listener not being triggered - Add processing smessage for CommandPubSubDecoder - Add unit-tests for CommandPubSubDecoder - Fix integration-test for RedissonSharedTopicTest - Add auto-find redis-server bin from PATH env variable Signed-off-by: Alexander Tulyakov --- .../client/handler/CommandPubSubDecoder.java | 15 +- .../handler/CommandPubSubDecoderTest.java | 227 ++++++++++++++++++ 2 files changed, 231 insertions(+), 11 deletions(-) create mode 100644 redisson/src/test/java/org/redisson/client/handler/CommandPubSubDecoderTest.java diff --git a/redisson/src/main/java/org/redisson/client/handler/CommandPubSubDecoder.java b/redisson/src/main/java/org/redisson/client/handler/CommandPubSubDecoder.java index c38676282..7aa6ec309 100644 --- a/redisson/src/main/java/org/redisson/client/handler/CommandPubSubDecoder.java +++ b/redisson/src/main/java/org/redisson/client/handler/CommandPubSubDecoder.java @@ -47,7 +47,8 @@ public class CommandPubSubDecoder extends CommandDecoder { private static final Set UNSUBSCRIBE_COMMANDS = new HashSet<>(Arrays.asList(RedisCommands.PUNSUBSCRIBE.getName(), RedisCommands.UNSUBSCRIBE.getName(), RedisCommands.SUNSUBSCRIBE.getName())); private static final Set SUBSCRIBE_COMMANDS = new HashSet<>(Arrays.asList(RedisCommands.PSUBSCRIBE.getName(), RedisCommands.SUBSCRIBE.getName(), RedisCommands.SSUBSCRIBE.getName())); - private static final Set MESSAGES = new HashSet(Arrays.asList("subscribe", "psubscribe", "punsubscribe", "unsubscribe", "ssubscribe", "sunsubscribe")); + private static final Set MESSAGES = new HashSet<>(Arrays.asList("subscribe", "psubscribe", "punsubscribe", "unsubscribe", "ssubscribe", "sunsubscribe")); + private static final Set TYPE_MESSAGES = new HashSet<>(Arrays.asList("message", "smessage", "pmessage")); // It is not needed to use concurrent map because responses are coming consecutive private final Map entries = new HashMap<>(); private final Map> commands = new ConcurrentHashMap<>(); @@ -222,20 +223,13 @@ public class CommandPubSubDecoder extends CommandDecoder { return null; } return commandData.getCommand().getReplayMultiDecoder(); - } else if ("message".equals(command)) { + } else if (TYPE_MESSAGES.contains(command)) { byte[] channelName = (byte[]) parts.get(1); PubSubEntry entry = entries.get(new ChannelName(channelName)); if (entry == null) { return null; } return entry.getDecoder(); - } else if ("pmessage".equals(command)) { - byte[] patternName = (byte[]) parts.get(1); - PubSubEntry entry = entries.get(new ChannelName(patternName)); - if (entry == null) { - return null; - } - return entry.getDecoder(); } else if ("pong".equals(command)) { return new ListObjectDecoder<>(0); } @@ -255,8 +249,7 @@ public class CommandPubSubDecoder extends CommandDecoder { if (parts.size() == 2 && "pmessage".equals(parts.get(0))) { return ByteArrayCodec.INSTANCE.getValueDecoder(); } - - if (parts.size() == 2 && "message".equals(parts.get(0))) { + if (parts.size() == 2 && TYPE_MESSAGES.contains(parts.get(0).toString())) { byte[] channelName = (byte[]) parts.get(1); return getDecoder(null, parts, channelName); } diff --git a/redisson/src/test/java/org/redisson/client/handler/CommandPubSubDecoderTest.java b/redisson/src/test/java/org/redisson/client/handler/CommandPubSubDecoderTest.java new file mode 100644 index 000000000..7e7d86a67 --- /dev/null +++ b/redisson/src/test/java/org/redisson/client/handler/CommandPubSubDecoderTest.java @@ -0,0 +1,227 @@ +package org.redisson.client.handler; + +import io.netty.channel.Channel; +import io.netty.channel.local.LocalChannel; +import io.netty.util.CharsetUtil; +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.ForkJoinPool; +import java.util.stream.Stream; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.ArgumentsProvider; +import org.junit.jupiter.params.provider.ArgumentsSource; +import org.redisson.client.ChannelName; +import org.redisson.client.RedisClientConfig; +import org.redisson.client.RedisConnection; +import org.redisson.client.RedisPubSubConnection; +import org.redisson.client.codec.ByteArrayCodec; +import org.redisson.client.codec.LongCodec; +import org.redisson.client.protocol.CommandData; +import org.redisson.client.protocol.Decoder; +import org.redisson.client.protocol.RedisCommand; +import org.redisson.client.protocol.decoder.MultiDecoder; +import org.redisson.client.protocol.decoder.ObjectDecoder; +import org.redisson.client.protocol.pubsub.PubSubStatusMessage; +import org.redisson.client.protocol.pubsub.PubSubType; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.fail; + +class CommandPubSubDecoderTest { + + private static class PartsArgumentsProvider implements ArgumentsProvider { + + @Override + public Stream provideArguments(ExtensionContext context) { + return Stream.of( + Arguments.of(Collections.singletonList("message")), + Arguments.of(Arrays.asList("pmessage", "test*".getBytes(CharsetUtil.UTF_8))), + Arguments.of(Arrays.asList("pmessage", "test*".getBytes(CharsetUtil.UTF_8), + "test1".getBytes(CharsetUtil.UTF_8))), + Arguments.of(Arrays.asList("smessage", "test".getBytes(CharsetUtil.UTF_8))), + Arguments.of(Arrays.asList("message", "test".getBytes(CharsetUtil.UTF_8))) + ); + } + } + + private static class SubscribePartsArgumentsProvider implements ArgumentsProvider { + @Override + public Stream provideArguments(ExtensionContext context) { + return Stream.of( + Arguments.of(new ObjectDecoder<>(LongCodec.INSTANCE.getValueDecoder()), + PubSubType.SSUBSCRIBE, Arrays.asList("smessage", + UUID.randomUUID() + .toString().getBytes( + CharsetUtil.UTF_8), + 123L)), + Arguments.of(new ObjectDecoder<>(LongCodec.INSTANCE.getValueDecoder()), + PubSubType.PSUBSCRIBE, Arrays.asList("pmessage", + "test*".getBytes(CharsetUtil.UTF_8), + "test1".getBytes(CharsetUtil.UTF_8), + 123L)), + Arguments.of(new ObjectDecoder<>(LongCodec.INSTANCE.getValueDecoder()), + PubSubType.SUBSCRIBE, Arrays.asList("message", + UUID.randomUUID() + .toString().getBytes( + CharsetUtil.UTF_8), + 123L)) + ); + } + } + + @ParameterizedTest + @ArgumentsSource(SubscribePartsArgumentsProvider.class) + void testPositiveSubscribeMessageDecoder(MultiDecoder multiDecoder, PubSubType subType, + List parts) { + // GIVEN + // initialize internal deps + Channel channel = new LocalChannel(); + RedisConnection connection = new RedisPubSubConnection(null, channel, null); + RedisClientConfig config = new RedisClientConfig().setAddress("redis://127.0.0.1:6379") + .setExecutor(new ForkJoinPool()); + CommandPubSubDecoder decoder = new CommandPubSubDecoder(config); + // do subscribe + ChannelName channelName = new ChannelName(new String((byte[]) parts.get(1), CharsetUtil.UTF_8)); + PubSubStatusMessage result = new PubSubStatusMessage(subType, channelName); + CommandData subscribeCommandData = + new CommandData<>(null, multiDecoder, null, + new RedisCommand<>(subType.name(), multiDecoder), null); + decoder.addPubSubCommand(channelName, subscribeCommandData); + try { + decoder.decodeResult(subscribeCommandData, parts, channel, result); + } catch (IOException e) { + fail(e); + } + // prepare message command + CommandData messageCommandData = + new CommandData<>(null, multiDecoder, null, + new RedisCommand<>((String) parts.get(0), multiDecoder), null); + // WHEN + MultiDecoder actualDecoder = decoder.messageDecoder(messageCommandData, parts); + //THEN + assertEquals(multiDecoder, actualDecoder); + } + + @Test + void testNegativeSubscribeMessageDecoder() { + // GIVEN + PubSubType subType = PubSubType.SUBSCRIBE; + List parts = Arrays.asList("message", + UUID.randomUUID().toString().getBytes(CharsetUtil.UTF_8)); + MultiDecoder subMultiDecoder = new ObjectDecoder<>( + ByteArrayCodec.INSTANCE.getValueDecoder()); + // initialize internal deps + Channel channel = new LocalChannel(); + RedisConnection connection = new RedisPubSubConnection(null, channel, null); + RedisClientConfig config = new RedisClientConfig().setAddress("redis://127.0.0.1:6379") + .setExecutor(new ForkJoinPool()); + CommandPubSubDecoder decoder = new CommandPubSubDecoder(config); + // do subscribe + ChannelName channelName = new ChannelName(new String((byte[]) parts.get(1), CharsetUtil.UTF_8)); + PubSubStatusMessage result = new PubSubStatusMessage(subType, channelName); + CommandData subscribeCommandData = + new CommandData<>(null, subMultiDecoder, null, + new RedisCommand<>(subType.name(), subMultiDecoder), null); + decoder.addPubSubCommand(channelName, subscribeCommandData); + try { + decoder.decodeResult(subscribeCommandData, parts, channel, result); + } catch (IOException e) { + fail(e); + } + // prepare message command + MultiDecoder msgMultiDecoder = new ObjectDecoder<>( + ByteArrayCodec.INSTANCE.getValueDecoder()); + CommandData messageCommandData = + new CommandData<>(null, msgMultiDecoder, null, + new RedisCommand<>((String) parts.get(0), msgMultiDecoder), null); + // WHEN + MultiDecoder actualDecoder = decoder.messageDecoder(messageCommandData, parts); + //THEN + assertNotEquals(msgMultiDecoder, actualDecoder); + assertEquals(subMultiDecoder, actualDecoder); + } + + @ParameterizedTest + @ArgumentsSource(SubscribePartsArgumentsProvider.class) + void testSelectDecoder(MultiDecoder multiDecoder, PubSubType subType, + List extendedPart) { + // GIVEN + List parts = extendedPart.subList(0, extendedPart.size() - 1); + // initialize internal deps + Channel channel = new LocalChannel(); + RedisConnection connection = new RedisPubSubConnection(null, channel, null); + RedisClientConfig config = new RedisClientConfig().setAddress("redis://127.0.0.1:6379") + .setExecutor(new ForkJoinPool()); + CommandPubSubDecoder decoder = new CommandPubSubDecoder(config); + // do subscribe + ChannelName channelName = new ChannelName(new String((byte[]) parts.get(1), CharsetUtil.UTF_8)); + PubSubStatusMessage result = new PubSubStatusMessage(subType, channelName); + CommandData subscribeCommandData = + new CommandData<>(null, multiDecoder, null, + new RedisCommand<>(subType.name(), multiDecoder), null); + decoder.addPubSubCommand(channelName, subscribeCommandData); + try { + decoder.decodeResult(subscribeCommandData, parts, channel, result); + } catch (IOException e) { + fail(e); + } + // WHEN + Decoder actualDecoder = decoder.selectDecoder(null, parts); + //THEN + assertEquals(multiDecoder.getDecoder(null, 0, null), actualDecoder); + } + + + @ParameterizedTest + @ArgumentsSource(PartsArgumentsProvider.class) + void testSelectDecoder(List parts) { + // GIVEN + RedisClientConfig config = new RedisClientConfig().setAddress("redis://127.0.0.1:6379") + .setExecutor(new ForkJoinPool()); + CommandPubSubDecoder decoder = new CommandPubSubDecoder(config); + Decoder expectedDecoder = ByteArrayCodec.INSTANCE.getValueDecoder(); + // WHEN + Decoder actualDecoder = decoder.selectDecoder(null, parts); + //THEN + assertEquals(expectedDecoder, actualDecoder); + } + + @Test + void testDifferentSelectDecoder() { + // GIVEN + MultiDecoder multiDecoder = new ObjectDecoder<>(LongCodec.INSTANCE.getValueDecoder()); + PubSubType subType = PubSubType.PSUBSCRIBE; + List parts = Arrays.asList("pmessage", "test*".getBytes(CharsetUtil.UTF_8)); + + // initialize internal deps + Channel channel = new LocalChannel(); + RedisConnection connection = new RedisPubSubConnection(null, channel, null); + RedisClientConfig config = new RedisClientConfig().setAddress("redis://127.0.0.1:6379") + .setExecutor(new ForkJoinPool()); + CommandPubSubDecoder decoder = new CommandPubSubDecoder(config); + // do subscribe + ChannelName channelName = new ChannelName(new String((byte[]) parts.get(1), CharsetUtil.UTF_8)); + PubSubStatusMessage result = new PubSubStatusMessage(subType, channelName); + CommandData subscribeCommandData = + new CommandData<>(null, multiDecoder, null, + new RedisCommand<>(subType.name(), multiDecoder), null); + decoder.addPubSubCommand(channelName, subscribeCommandData); + try { + decoder.decodeResult(subscribeCommandData, parts, channel, result); + } catch (IOException e) { + fail(e); + } + // WHEN + Decoder actualDecoder = decoder.selectDecoder(null, parts); + //THEN + assertNotEquals(multiDecoder.getDecoder(null, 0, null), actualDecoder); + assertEquals(ByteArrayCodec.INSTANCE.getValueDecoder(), actualDecoder); + } +} \ No newline at end of file From 4c8c792ccb6fbdf8ea8c286d829a9bf476ce8d63 Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Thu, 22 Dec 2022 10:42:47 +0300 Subject: [PATCH 52/58] refactoring --- .../src/main/java/org/redisson/RedissonLiveObjectService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/redisson/src/main/java/org/redisson/RedissonLiveObjectService.java b/redisson/src/main/java/org/redisson/RedissonLiveObjectService.java index a3186d677..59af0ce41 100644 --- a/redisson/src/main/java/org/redisson/RedissonLiveObjectService.java +++ b/redisson/src/main/java/org/redisson/RedissonLiveObjectService.java @@ -258,6 +258,7 @@ public class RedissonLiveObjectService implements RLiveObjectService { private T persist(T detachedObject, Map alreadyPersisted, RCascadeType type) { + validateDetached(detachedObject); Object id = getId(detachedObject); T attachedObject = attach(detachedObject); From 4f0258f2b6579697fa1228ecf7a8a626d88ea356 Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Thu, 22 Dec 2022 11:34:51 +0300 Subject: [PATCH 53/58] RedissonShardedTopicTest should use docker container --- pom.xml | 7 ++++ redisson/pom.xml | 5 +++ .../redisson/RedissonShardedTopicTest.java | 32 +++++++++++++++---- 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index 2c804dfe2..3ea909b49 100644 --- a/pom.xml +++ b/pom.xml @@ -172,6 +172,13 @@ test + + org.testcontainers + testcontainers-bom + 1.17.6 + pom + import + io.netty netty-bom diff --git a/redisson/pom.xml b/redisson/pom.xml index de0ef5b96..ae7991086 100644 --- a/redisson/pom.xml +++ b/redisson/pom.xml @@ -126,6 +126,11 @@ logback-classic test + + org.testcontainers + junit-jupiter + test + org.apache.tomcat.embed diff --git a/redisson/src/test/java/org/redisson/RedissonShardedTopicTest.java b/redisson/src/test/java/org/redisson/RedissonShardedTopicTest.java index 8978623d5..981ab50b3 100644 --- a/redisson/src/test/java/org/redisson/RedissonShardedTopicTest.java +++ b/redisson/src/test/java/org/redisson/RedissonShardedTopicTest.java @@ -7,6 +7,10 @@ import org.redisson.api.RTopic; import org.redisson.api.RedissonClient; import org.redisson.config.Config; import org.redisson.connection.balancer.RandomLoadBalancer; +import org.testcontainers.containers.FixedHostPortGenericContainer; +import org.testcontainers.containers.startupcheck.MinimumDurationRunningStartupCheckStrategy; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; import java.time.Duration; import java.util.HashMap; @@ -15,19 +19,34 @@ import java.util.concurrent.atomic.AtomicInteger; import static org.assertj.core.api.Assertions.assertThat; +@Testcontainers public class RedissonShardedTopicTest { + @Container + private final FixedHostPortGenericContainer redisClusterContainer = + new FixedHostPortGenericContainer<>("vishnunair/docker-redis-cluster") + .withFixedExposedPort(5000, 6379) + .withFixedExposedPort(5001, 6380) + .withFixedExposedPort(5002, 6381) + .withFixedExposedPort(5003, 6382) + .withFixedExposedPort(5004, 6383) + .withFixedExposedPort(5005, 6384) + .withStartupCheckStrategy( + new MinimumDurationRunningStartupCheckStrategy(Duration.ofSeconds(6)) + ); @Test public void testClusterSharding() { Config config = new Config(); HostPortNatMapper m = new HostPortNatMapper(); Map mm = new HashMap<>(); - mm.put("172.17.0.2:6380", "127.0.0.1:5001"); - mm.put("172.17.0.2:6382", "127.0.0.1:5003"); - mm.put("172.17.0.2:6379", "127.0.0.1:5000"); - mm.put("172.17.0.2:6383", "127.0.0.1:5004"); - mm.put("172.17.0.2:6384", "127.0.0.1:5005"); - mm.put("172.17.0.2:6381", "127.0.0.1:5002"); + + String ip = redisClusterContainer.getCurrentContainerInfo().getNetworkSettings().getIpAddress(); + mm.put(ip + ":6380", "127.0.0.1:5001"); + mm.put(ip + ":6382", "127.0.0.1:5003"); + mm.put(ip + ":6379", "127.0.0.1:5000"); + mm.put(ip + ":6383", "127.0.0.1:5004"); + mm.put(ip + ":6384", "127.0.0.1:5005"); + mm.put(ip + ":6381", "127.0.0.1:5002"); m.setHostsPortMap(mm); config.useClusterServers() .setPingConnectionInterval(0) @@ -60,6 +79,7 @@ public class RedissonShardedTopicTest { } redisson.shutdown(); + } From ad5b902d7fea6c3e453e2f5577b2c9cf9550e4ea Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Fri, 23 Dec 2022 09:25:42 +0300 Subject: [PATCH 54/58] refactoring --- .../redisson/RedissonShardedTopicTest.java | 44 +++++++++---------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/redisson/src/test/java/org/redisson/RedissonShardedTopicTest.java b/redisson/src/test/java/org/redisson/RedissonShardedTopicTest.java index 981ab50b3..c683bedeb 100644 --- a/redisson/src/test/java/org/redisson/RedissonShardedTopicTest.java +++ b/redisson/src/test/java/org/redisson/RedissonShardedTopicTest.java @@ -3,12 +3,17 @@ package org.redisson; import org.awaitility.Awaitility; import org.junit.jupiter.api.Test; import org.redisson.api.HostPortNatMapper; +import org.redisson.api.NatMapper; import org.redisson.api.RTopic; import org.redisson.api.RedissonClient; import org.redisson.config.Config; import org.redisson.connection.balancer.RandomLoadBalancer; +import org.redisson.misc.RedisURI; import org.testcontainers.containers.FixedHostPortGenericContainer; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.startupcheck.IsRunningStartupCheckStrategy; import org.testcontainers.containers.startupcheck.MinimumDurationRunningStartupCheckStrategy; +import org.testcontainers.containers.wait.strategy.HostPortWaitStrategy; import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; @@ -23,36 +28,29 @@ import static org.assertj.core.api.Assertions.assertThat; public class RedissonShardedTopicTest { @Container - private final FixedHostPortGenericContainer redisClusterContainer = - new FixedHostPortGenericContainer<>("vishnunair/docker-redis-cluster") - .withFixedExposedPort(5000, 6379) - .withFixedExposedPort(5001, 6380) - .withFixedExposedPort(5002, 6381) - .withFixedExposedPort(5003, 6382) - .withFixedExposedPort(5004, 6383) - .withFixedExposedPort(5005, 6384) - .withStartupCheckStrategy( - new MinimumDurationRunningStartupCheckStrategy(Duration.ofSeconds(6)) - ); + private final GenericContainer redisClusterContainer = + new GenericContainer<>("vishnunair/docker-redis-cluster") + .withExposedPorts(6379, 6380, 6381, 6382, 6383, 6384) + .withStartupCheckStrategy( + new MinimumDurationRunningStartupCheckStrategy(Duration.ofSeconds(6)) + ); @Test public void testClusterSharding() { Config config = new Config(); - HostPortNatMapper m = new HostPortNatMapper(); - Map mm = new HashMap<>(); - String ip = redisClusterContainer.getCurrentContainerInfo().getNetworkSettings().getIpAddress(); - mm.put(ip + ":6380", "127.0.0.1:5001"); - mm.put(ip + ":6382", "127.0.0.1:5003"); - mm.put(ip + ":6379", "127.0.0.1:5000"); - mm.put(ip + ":6383", "127.0.0.1:5004"); - mm.put(ip + ":6384", "127.0.0.1:5005"); - mm.put(ip + ":6381", "127.0.0.1:5002"); - m.setHostsPortMap(mm); config.useClusterServers() .setPingConnectionInterval(0) - .setNatMapper(m) + .setNatMapper(new NatMapper() { + @Override + public RedisURI map(RedisURI uri) { + if (redisClusterContainer.getMappedPort(uri.getPort()) == null) { + return uri; + } + return new RedisURI(uri.getScheme(), redisClusterContainer.getHost(), redisClusterContainer.getMappedPort(uri.getPort())); + } + }) .setLoadBalancer(new RandomLoadBalancer()) - .addNodeAddress("redis://127.0.0.1:5000"); + .addNodeAddress("redis://127.0.0.1:" + redisClusterContainer.getFirstMappedPort()); RedissonClient redisson = Redisson.create(config); AtomicInteger counter = new AtomicInteger(); From efd936f4c2b9a9ad3fa6631d0696056e1a634eae Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Fri, 23 Dec 2022 09:55:16 +0300 Subject: [PATCH 55/58] Fixed - RBatch.getListMultimapCache() method should return RMultimapCacheAsync. #4758 --- redisson/src/main/java/org/redisson/api/RBatch.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/redisson/src/main/java/org/redisson/api/RBatch.java b/redisson/src/main/java/org/redisson/api/RBatch.java index 59a6ca0ee..f8d80feca 100644 --- a/redisson/src/main/java/org/redisson/api/RBatch.java +++ b/redisson/src/main/java/org/redisson/api/RBatch.java @@ -258,7 +258,7 @@ public interface RBatch { * @param name - name of object * @return ListMultimapCache object */ - RMultimapAsync getListMultimapCache(String name); + RMultimapCacheAsync getListMultimapCache(String name); /** * Returns List based Multimap instance by name @@ -273,7 +273,7 @@ public interface RBatch { * @param codec - codec for keys and values * @return ListMultimapCache object */ - RMultimapAsync getListMultimapCache(String name, Codec codec); + RMultimapCacheAsync getListMultimapCache(String name, Codec codec); /** * Returns map instance by name. From 66db3da09974da0886b54322ef1900e5c0deae51 Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Fri, 23 Dec 2022 10:23:49 +0300 Subject: [PATCH 56/58] helidon updated --- redisson-helidon/README.md | 4 ++-- redisson-helidon/redisson-helidon-30/pom.xml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/redisson-helidon/README.md b/redisson-helidon/README.md index 32914b2b8..9ae8f5fda 100644 --- a/redisson-helidon/README.md +++ b/redisson-helidon/README.md @@ -2,7 +2,7 @@ Integrates Redisson with [Helidon](https://helidon.io/) framework. -Supports Helidon 1.4.x - 3.0.x +Supports Helidon 1.4.x - 3.x.x ## Usage @@ -26,7 +26,7 @@ Gradle ```groovy // for Helidon v1.4.x - v2.5.x compile 'org.redisson:redisson-helidon-20:3.19.0' -// for Helidon v3.0.x +// for Helidon v3.x.x compile 'org.redisson:redisson-helidon-30:3.19.0' ``` diff --git a/redisson-helidon/redisson-helidon-30/pom.xml b/redisson-helidon/redisson-helidon-30/pom.xml index da7adb895..10babcae4 100644 --- a/redisson-helidon/redisson-helidon-30/pom.xml +++ b/redisson-helidon/redisson-helidon-30/pom.xml @@ -82,7 +82,7 @@ io.helidon.microprofile.config helidon-microprofile-config - 3.0.0 + 3.1.0 runtime true @@ -90,14 +90,14 @@ org.eclipse.microprofile.config microprofile-config-api - 3.0.1 + 3.0.2 compile io.helidon.microprofile.cdi helidon-microprofile-cdi - 3.0.0 + 3.1.0 test From ac93cbc48fe91d16fde690c57272e0a11c612077 Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Thu, 29 Dec 2022 09:24:58 +0300 Subject: [PATCH 57/58] Fixed - Pattern Topic messages duplication after failover in cluster #4766 --- .../pubsub/PublishSubscribeService.java | 27 ++++- .../redisson/RedissonTopicPatternTest.java | 114 +++++++++++++++--- 2 files changed, 117 insertions(+), 24 deletions(-) diff --git a/redisson/src/main/java/org/redisson/pubsub/PublishSubscribeService.java b/redisson/src/main/java/org/redisson/pubsub/PublishSubscribeService.java index a030c1063..48571e01f 100644 --- a/redisson/src/main/java/org/redisson/pubsub/PublishSubscribeService.java +++ b/redisson/src/main/java/org/redisson/pubsub/PublishSubscribeService.java @@ -622,7 +622,7 @@ public class PublishSubscribeService { } if (topicType == PubSubType.PUNSUBSCRIBE) { - psubscribe(channelName, listeners, subscribeCodec); + psubscribe(en, channelName, listeners, subscribeCodec); } else if (topicType == PubSubType.SUNSUBSCRIBE) { ssubscribe(channelName, listeners, subscribeCodec); } else { @@ -664,14 +664,29 @@ public class PublishSubscribeService { }); } - private void psubscribe(ChannelName channelName, Collection> listeners, - Codec subscribeCodec) { - CompletableFuture> subscribeFuture = - psubscribe(channelName, subscribeCodec, listeners.toArray(new RedisPubSubListener[0])); + private void psubscribe(MasterSlaveEntry oldEntry, ChannelName channelName, Collection> listeners, + Codec subscribeCodec) { + MasterSlaveEntry entry = getEntry(channelName); + if (isMultiEntity(channelName)) { + entry = connectionManager.getEntrySet() + .stream() + .filter(e -> !name2PubSubConnection.containsKey(new PubSubKey(channelName, e)) && e != oldEntry) + .findFirst() + .orElse(null); + } + if (entry == null) { + connectionManager.newTimeout(task -> { + psubscribe(oldEntry, channelName, listeners, subscribeCodec); + }, 1, TimeUnit.SECONDS); + return; + } + + CompletableFuture subscribeFuture = + subscribe(PubSubType.PSUBSCRIBE, subscribeCodec, channelName, entry, listeners.toArray(new RedisPubSubListener[0])); subscribeFuture.whenComplete((res, e) -> { if (e != null) { connectionManager.newTimeout(task -> { - psubscribe(channelName, listeners, subscribeCodec); + psubscribe(oldEntry, channelName, listeners, subscribeCodec); }, 1, TimeUnit.SECONDS); return; } diff --git a/redisson/src/test/java/org/redisson/RedissonTopicPatternTest.java b/redisson/src/test/java/org/redisson/RedissonTopicPatternTest.java index 85440ff63..31f3d1752 100644 --- a/redisson/src/test/java/org/redisson/RedissonTopicPatternTest.java +++ b/redisson/src/test/java/org/redisson/RedissonTopicPatternTest.java @@ -1,27 +1,10 @@ package org.redisson; -import static org.assertj.core.api.Assertions.assertThat; -import static org.awaitility.Awaitility.await; - -import java.io.IOException; -import java.io.Serializable; -import java.time.Duration; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; - import org.awaitility.Awaitility; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.redisson.RedisRunner.RedisProcess; +import org.redisson.api.RBucket; import org.redisson.api.RPatternTopic; import org.redisson.api.RTopic; import org.redisson.api.RedissonClient; @@ -30,8 +13,21 @@ import org.redisson.api.listener.PatternMessageListener; import org.redisson.api.listener.PatternStatusListener; import org.redisson.client.codec.StringCodec; import org.redisson.config.Config; +import org.redisson.config.SubscriptionMode; import org.redisson.connection.balancer.RandomLoadBalancer; +import java.io.IOException; +import java.io.Serializable; +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.awaitility.Awaitility.await; + public class RedissonTopicPatternTest extends BaseTest { public static class Message implements Serializable { @@ -378,6 +374,88 @@ public class RedissonTopicPatternTest extends BaseTest { } } + @Test + public void testReattachInClusterMaster() throws Exception { + RedisRunner master1 = new RedisRunner().randomPort().randomDir().nosave() + .notifyKeyspaceEvents( + RedisRunner.KEYSPACE_EVENTS_OPTIONS.K, + RedisRunner.KEYSPACE_EVENTS_OPTIONS.g, + RedisRunner.KEYSPACE_EVENTS_OPTIONS.E, + RedisRunner.KEYSPACE_EVENTS_OPTIONS.$); + RedisRunner master2 = new RedisRunner().randomPort().randomDir().nosave() + .notifyKeyspaceEvents( + RedisRunner.KEYSPACE_EVENTS_OPTIONS.K, + RedisRunner.KEYSPACE_EVENTS_OPTIONS.g, + RedisRunner.KEYSPACE_EVENTS_OPTIONS.E, + RedisRunner.KEYSPACE_EVENTS_OPTIONS.$); + RedisRunner master3 = new RedisRunner().randomPort().randomDir().nosave() + .notifyKeyspaceEvents( + RedisRunner.KEYSPACE_EVENTS_OPTIONS.K, + RedisRunner.KEYSPACE_EVENTS_OPTIONS.g, + RedisRunner.KEYSPACE_EVENTS_OPTIONS.E, + RedisRunner.KEYSPACE_EVENTS_OPTIONS.$); + RedisRunner slave1 = new RedisRunner().randomPort().randomDir().nosave() + .notifyKeyspaceEvents( + RedisRunner.KEYSPACE_EVENTS_OPTIONS.K, + RedisRunner.KEYSPACE_EVENTS_OPTIONS.g, + RedisRunner.KEYSPACE_EVENTS_OPTIONS.E, + RedisRunner.KEYSPACE_EVENTS_OPTIONS.$); + RedisRunner slave2 = new RedisRunner().randomPort().randomDir().nosave() + .notifyKeyspaceEvents( + RedisRunner.KEYSPACE_EVENTS_OPTIONS.K, + RedisRunner.KEYSPACE_EVENTS_OPTIONS.g, + RedisRunner.KEYSPACE_EVENTS_OPTIONS.E, + RedisRunner.KEYSPACE_EVENTS_OPTIONS.$); + RedisRunner slave3 = new RedisRunner().randomPort().randomDir().nosave() + .notifyKeyspaceEvents( + RedisRunner.KEYSPACE_EVENTS_OPTIONS.K, + RedisRunner.KEYSPACE_EVENTS_OPTIONS.g, + RedisRunner.KEYSPACE_EVENTS_OPTIONS.E, + RedisRunner.KEYSPACE_EVENTS_OPTIONS.$); + + + ClusterRunner clusterRunner = new ClusterRunner() + .addNode(master1, slave1) + .addNode(master2, slave2) + .addNode(master3, slave3); + ClusterRunner.ClusterProcesses process = clusterRunner.run(); + + Config config = new Config(); + config.useClusterServers() + .setSubscriptionMode(SubscriptionMode.MASTER) + .setLoadBalancer(new RandomLoadBalancer()) + .addNodeAddress(process.getNodes().stream().findAny().get().getRedisServerAddressAndPort()); + RedissonClient redisson = Redisson.create(config); + + AtomicInteger executions = new AtomicInteger(); + + RPatternTopic topic = redisson.getPatternTopic("__keyevent@*:del", StringCodec.INSTANCE); + topic.addListener(String.class, new PatternMessageListener() { + @Override + public void onMessage(CharSequence pattern, CharSequence channel, String msg) { + executions.incrementAndGet(); + } + }); + + process.getNodes().stream().filter(x -> master1.getPort() == x.getRedisServerPort()) + .forEach(x -> { + x.stop(); + }); + + Thread.sleep(40000); + + for (int i = 0; i < 100; i++) { + RBucket b = redisson.getBucket("test" + i); + b.set(i); + b.delete(); + } + Thread.sleep(100); + assertThat(executions.get()).isEqualTo(100); + + redisson.shutdown(); + process.shutdown(); + } + @Test public void testReattach() throws InterruptedException, IOException, ExecutionException, TimeoutException { RedisProcess runner = new RedisRunner() From 69b71104cfd5a2388afac6ca29b4661542e86015 Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Thu, 29 Dec 2022 11:06:38 +0300 Subject: [PATCH 58/58] Fixed - RReliableTopic doesn't remove all expired subscribers at once. #4765 --- .../org/redisson/RedissonReliableTopic.java | 10 ++--- .../redisson/RedissonReliableTopicTest.java | 37 +++++++++++++++++++ 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/redisson/src/main/java/org/redisson/RedissonReliableTopic.java b/redisson/src/main/java/org/redisson/RedissonReliableTopic.java index 69d6125e8..ec687573e 100644 --- a/redisson/src/main/java/org/redisson/RedissonReliableTopic.java +++ b/redisson/src/main/java/org/redisson/RedissonReliableTopic.java @@ -225,11 +225,11 @@ public class RedissonReliableTopic extends RedissonExpirable implements RReliabl + "redis.call('hset', KEYS[3], ARGV[2], ARGV[1]); " + "end; " - + "local t = redis.call('zrange', KEYS[5], 0, 0, 'WITHSCORES'); " - + "if #t == 2 and tonumber(t[2]) < tonumber(ARGV[3]) then " - + "redis.call('hdel', KEYS[3], t[1]); " - + "redis.call('zrem', KEYS[2], t[1]); " - + "redis.call('zrem', KEYS[5], t[1]); " + + "local expired = redis.call('zrangebyscore', KEYS[5], 0, tonumber(ARGV[3]) - 1); " + + "for i, v in ipairs(expired) do " + + "redis.call('hdel', KEYS[3], v); " + + "redis.call('zrem', KEYS[2], v); " + + "redis.call('zrem', KEYS[5], v); " + "end; " + "local v = redis.call('zrange', KEYS[2], 0, 0); " diff --git a/redisson/src/test/java/org/redisson/RedissonReliableTopicTest.java b/redisson/src/test/java/org/redisson/RedissonReliableTopicTest.java index 3d46306dc..23e3840ca 100644 --- a/redisson/src/test/java/org/redisson/RedissonReliableTopicTest.java +++ b/redisson/src/test/java/org/redisson/RedissonReliableTopicTest.java @@ -3,6 +3,8 @@ package org.redisson; import org.awaitility.Awaitility; import org.junit.jupiter.api.Test; import org.redisson.api.RReliableTopic; +import org.redisson.api.RedissonClient; +import org.redisson.config.Config; import java.time.Duration; import java.util.LinkedList; @@ -20,6 +22,41 @@ import static org.assertj.core.api.Assertions.assertThat; */ public class RedissonReliableTopicTest extends BaseTest { + @Test + public void testRemoveExpiredSubscribers() throws InterruptedException { + RReliableTopic rt = redisson.getReliableTopic("test1"); + AtomicInteger counter = new AtomicInteger(); + rt.addListener(Integer.class, (ch, m) -> { + counter.incrementAndGet(); + }); + + Config config = new Config(); + config.setReliableTopicWatchdogTimeout(1000); + config.useSingleServer() + .setAddress(RedisRunner.getDefaultRedisServerBindAddressAndPort()); + RedissonClient secondInstance = Redisson.create(config); + RReliableTopic rt2 = secondInstance.getReliableTopic("test1"); + rt2.addListener(Integer.class, (ch, m) -> { + counter.incrementAndGet(); + }); + + assertThat(rt2.countSubscribers()).isEqualTo(2); + + secondInstance.shutdown(); + + Thread.sleep(1500); + + for (int i = 0; i < 10; i++) { + rt.publish(i); + } + + Thread.sleep(100); + + assertThat(rt.countSubscribers()).isEqualTo(1); + assertThat(counter.get()).isEqualTo(10); + assertThat(rt.size()).isEqualTo(0); + } + @Test public void testAutoTrim() { RReliableTopic rt = redisson.getReliableTopic("test1");