diff --git a/redisson-spring-data/redisson-spring-data-16/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java b/redisson-spring-data/redisson-spring-data-16/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java index b972e7544..d61a2ca2c 100644 --- a/redisson-spring-data/redisson-spring-data-16/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java +++ b/redisson-spring-data/redisson-spring-data-16/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java @@ -32,6 +32,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.concurrent.CompletableFuture; /** * @@ -51,9 +52,9 @@ public class RedissonSubscription extends AbstractSubscription { @Override protected void doSubscribe(byte[]... channels) { - List> list = new ArrayList<>(); + List> list = new ArrayList<>(); for (byte[] channel : channels) { - RFuture f = subscribeService.subscribe(ByteArrayCodec.INSTANCE, new ChannelName(channel), new BaseRedisPubSubListener() { + CompletableFuture f = subscribeService.subscribe(ByteArrayCodec.INSTANCE, new ChannelName(channel), new BaseRedisPubSubListener() { @Override public void onMessage(CharSequence ch, Object message) { if (!Arrays.equals(((ChannelName) ch).getName(), channel)) { @@ -67,7 +68,7 @@ public class RedissonSubscription extends AbstractSubscription { }); list.add(f); } - for (RFuture future : list) { + for (CompletableFuture future : list) { commandExecutor.syncSubscription(future); } } @@ -81,9 +82,9 @@ public class RedissonSubscription extends AbstractSubscription { @Override protected void doPsubscribe(byte[]... patterns) { - List> list = new ArrayList<>(); + List> list = new ArrayList<>(); for (byte[] channel : patterns) { - RFuture> f = subscribeService.psubscribe(new ChannelName(channel), ByteArrayCodec.INSTANCE, new BaseRedisPubSubListener() { + CompletableFuture> f = subscribeService.psubscribe(new ChannelName(channel), ByteArrayCodec.INSTANCE, new BaseRedisPubSubListener() { @Override public void onPatternMessage(CharSequence pattern, CharSequence ch, Object message) { if (!Arrays.equals(((ChannelName) pattern).getName(), channel)) { @@ -97,7 +98,7 @@ public class RedissonSubscription extends AbstractSubscription { }); list.add(f); } - for (RFuture future : list) { + for (CompletableFuture future : list) { commandExecutor.syncSubscription(future); } } diff --git a/redisson-spring-data/redisson-spring-data-17/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java b/redisson-spring-data/redisson-spring-data-17/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java index b972e7544..d61a2ca2c 100644 --- a/redisson-spring-data/redisson-spring-data-17/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java +++ b/redisson-spring-data/redisson-spring-data-17/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java @@ -32,6 +32,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.concurrent.CompletableFuture; /** * @@ -51,9 +52,9 @@ public class RedissonSubscription extends AbstractSubscription { @Override protected void doSubscribe(byte[]... channels) { - List> list = new ArrayList<>(); + List> list = new ArrayList<>(); for (byte[] channel : channels) { - RFuture f = subscribeService.subscribe(ByteArrayCodec.INSTANCE, new ChannelName(channel), new BaseRedisPubSubListener() { + CompletableFuture f = subscribeService.subscribe(ByteArrayCodec.INSTANCE, new ChannelName(channel), new BaseRedisPubSubListener() { @Override public void onMessage(CharSequence ch, Object message) { if (!Arrays.equals(((ChannelName) ch).getName(), channel)) { @@ -67,7 +68,7 @@ public class RedissonSubscription extends AbstractSubscription { }); list.add(f); } - for (RFuture future : list) { + for (CompletableFuture future : list) { commandExecutor.syncSubscription(future); } } @@ -81,9 +82,9 @@ public class RedissonSubscription extends AbstractSubscription { @Override protected void doPsubscribe(byte[]... patterns) { - List> list = new ArrayList<>(); + List> list = new ArrayList<>(); for (byte[] channel : patterns) { - RFuture> f = subscribeService.psubscribe(new ChannelName(channel), ByteArrayCodec.INSTANCE, new BaseRedisPubSubListener() { + CompletableFuture> f = subscribeService.psubscribe(new ChannelName(channel), ByteArrayCodec.INSTANCE, new BaseRedisPubSubListener() { @Override public void onPatternMessage(CharSequence pattern, CharSequence ch, Object message) { if (!Arrays.equals(((ChannelName) pattern).getName(), channel)) { @@ -97,7 +98,7 @@ public class RedissonSubscription extends AbstractSubscription { }); list.add(f); } - for (RFuture future : list) { + for (CompletableFuture future : list) { commandExecutor.syncSubscription(future); } } diff --git a/redisson-spring-data/redisson-spring-data-18/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java b/redisson-spring-data/redisson-spring-data-18/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java index b972e7544..d61a2ca2c 100644 --- a/redisson-spring-data/redisson-spring-data-18/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java +++ b/redisson-spring-data/redisson-spring-data-18/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java @@ -32,6 +32,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.concurrent.CompletableFuture; /** * @@ -51,9 +52,9 @@ public class RedissonSubscription extends AbstractSubscription { @Override protected void doSubscribe(byte[]... channels) { - List> list = new ArrayList<>(); + List> list = new ArrayList<>(); for (byte[] channel : channels) { - RFuture f = subscribeService.subscribe(ByteArrayCodec.INSTANCE, new ChannelName(channel), new BaseRedisPubSubListener() { + CompletableFuture f = subscribeService.subscribe(ByteArrayCodec.INSTANCE, new ChannelName(channel), new BaseRedisPubSubListener() { @Override public void onMessage(CharSequence ch, Object message) { if (!Arrays.equals(((ChannelName) ch).getName(), channel)) { @@ -67,7 +68,7 @@ public class RedissonSubscription extends AbstractSubscription { }); list.add(f); } - for (RFuture future : list) { + for (CompletableFuture future : list) { commandExecutor.syncSubscription(future); } } @@ -81,9 +82,9 @@ public class RedissonSubscription extends AbstractSubscription { @Override protected void doPsubscribe(byte[]... patterns) { - List> list = new ArrayList<>(); + List> list = new ArrayList<>(); for (byte[] channel : patterns) { - RFuture> f = subscribeService.psubscribe(new ChannelName(channel), ByteArrayCodec.INSTANCE, new BaseRedisPubSubListener() { + CompletableFuture> f = subscribeService.psubscribe(new ChannelName(channel), ByteArrayCodec.INSTANCE, new BaseRedisPubSubListener() { @Override public void onPatternMessage(CharSequence pattern, CharSequence ch, Object message) { if (!Arrays.equals(((ChannelName) pattern).getName(), channel)) { @@ -97,7 +98,7 @@ public class RedissonSubscription extends AbstractSubscription { }); list.add(f); } - for (RFuture future : list) { + for (CompletableFuture future : list) { commandExecutor.syncSubscription(future); } } diff --git a/redisson-spring-data/redisson-spring-data-20/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java b/redisson-spring-data/redisson-spring-data-20/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java index 79d8e246f..75b3c6d06 100644 --- a/redisson-spring-data/redisson-spring-data-20/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java +++ b/redisson-spring-data/redisson-spring-data-20/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java @@ -32,6 +32,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.concurrent.CompletableFuture; /** * @@ -51,9 +52,9 @@ public class RedissonSubscription extends AbstractSubscription { @Override protected void doSubscribe(byte[]... channels) { - List> list = new ArrayList<>(); + List> list = new ArrayList<>(); for (byte[] channel : channels) { - RFuture f = subscribeService.subscribe(ByteArrayCodec.INSTANCE, new ChannelName(channel), new BaseRedisPubSubListener() { + CompletableFuture f = subscribeService.subscribe(ByteArrayCodec.INSTANCE, new ChannelName(channel), new BaseRedisPubSubListener() { @Override public void onMessage(CharSequence ch, Object message) { if (!Arrays.equals(((ChannelName) ch).getName(), channel)) { @@ -67,7 +68,7 @@ public class RedissonSubscription extends AbstractSubscription { }); list.add(f); } - for (RFuture future : list) { + for (CompletableFuture future : list) { commandExecutor.syncSubscription(future); } } @@ -81,9 +82,9 @@ public class RedissonSubscription extends AbstractSubscription { @Override protected void doPsubscribe(byte[]... patterns) { - List> list = new ArrayList<>(); + List> list = new ArrayList<>(); for (byte[] channel : patterns) { - RFuture> f = subscribeService.psubscribe(new ChannelName(channel), ByteArrayCodec.INSTANCE, new BaseRedisPubSubListener() { + CompletableFuture> f = subscribeService.psubscribe(new ChannelName(channel), ByteArrayCodec.INSTANCE, new BaseRedisPubSubListener() { @Override public void onPatternMessage(CharSequence pattern, CharSequence ch, Object message) { if (!Arrays.equals(((ChannelName) pattern).getName(), channel)) { @@ -97,7 +98,7 @@ public class RedissonSubscription extends AbstractSubscription { }); list.add(f); } - for (RFuture future : list) { + for (CompletableFuture future : list) { commandExecutor.syncSubscription(future); } } diff --git a/redisson-spring-data/redisson-spring-data-21/src/main/java/org/redisson/spring/data/connection/RedissonReactiveSubscription.java b/redisson-spring-data/redisson-spring-data-21/src/main/java/org/redisson/spring/data/connection/RedissonReactiveSubscription.java index c890ef263..02b027b31 100644 --- a/redisson-spring-data/redisson-spring-data-21/src/main/java/org/redisson/spring/data/connection/RedissonReactiveSubscription.java +++ b/redisson-spring-data/redisson-spring-data-21/src/main/java/org/redisson/spring/data/connection/RedissonReactiveSubscription.java @@ -32,10 +32,9 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import java.nio.ByteBuffer; -import java.util.Collection; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Set; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; @@ -98,20 +97,21 @@ public class RedissonReactiveSubscription implements ReactiveSubscription { public Mono subscribe(ByteBuffer... channels) { monosListener.acquire(); return Mono.defer(() -> { - RedissonPromise result = new RedissonPromise<>(); - result.onComplete((r, ex) -> { - monosListener.release(); - }); - CountableListener listener = new CountableListener<>(result, null, channels.length); + List> futures = new ArrayList<>(); for (ByteBuffer channel : channels) { ChannelName cn = toChannelName(channel); - RFuture f = subscribeService.subscribe(ByteArrayCodec.INSTANCE, cn); - f.onComplete((res, e) -> RedissonReactiveSubscription.this.channels.put(cn, res)); - f.onComplete(listener); + CompletableFuture f = subscribeService.subscribe(ByteArrayCodec.INSTANCE, cn); + f = f.whenComplete((res, e) -> RedissonReactiveSubscription.this.channels.put(cn, res)); + futures.add(f); } - return Mono.fromFuture(result); + CompletableFuture future = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); + future = future.whenComplete((r, e) -> { + monosListener.release(); + }); + return Mono.fromFuture(future); }); + } protected ChannelName toChannelName(ByteBuffer channel) { @@ -122,18 +122,19 @@ public class RedissonReactiveSubscription implements ReactiveSubscription { public Mono pSubscribe(ByteBuffer... patterns) { monosListener.acquire(); return Mono.defer(() -> { - RedissonPromise result = new RedissonPromise<>(); - result.onComplete((r, ex) -> { - monosListener.release(); - }); - CountableListener listener = new CountableListener<>(result, null, patterns.length); + List> futures = new ArrayList<>(); for (ByteBuffer channel : patterns) { ChannelName cn = toChannelName(channel); - RFuture> f = subscribeService.psubscribe(cn, ByteArrayCodec.INSTANCE); - f.onComplete((res, e) -> RedissonReactiveSubscription.this.patterns.put(cn, res)); - f.onComplete(listener); + CompletableFuture> f = subscribeService.psubscribe(cn, ByteArrayCodec.INSTANCE); + f = f.whenComplete((res, e) -> RedissonReactiveSubscription.this.patterns.put(cn, res)); + futures.add(f); } - return Mono.fromFuture(result); + + CompletableFuture future = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); + future = future.whenComplete((r, e) -> { + monosListener.release(); + }); + return Mono.fromFuture(future); }); } diff --git a/redisson-spring-data/redisson-spring-data-21/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java b/redisson-spring-data/redisson-spring-data-21/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java index b972e7544..d61a2ca2c 100644 --- a/redisson-spring-data/redisson-spring-data-21/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java +++ b/redisson-spring-data/redisson-spring-data-21/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java @@ -32,6 +32,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.concurrent.CompletableFuture; /** * @@ -51,9 +52,9 @@ public class RedissonSubscription extends AbstractSubscription { @Override protected void doSubscribe(byte[]... channels) { - List> list = new ArrayList<>(); + List> list = new ArrayList<>(); for (byte[] channel : channels) { - RFuture f = subscribeService.subscribe(ByteArrayCodec.INSTANCE, new ChannelName(channel), new BaseRedisPubSubListener() { + CompletableFuture f = subscribeService.subscribe(ByteArrayCodec.INSTANCE, new ChannelName(channel), new BaseRedisPubSubListener() { @Override public void onMessage(CharSequence ch, Object message) { if (!Arrays.equals(((ChannelName) ch).getName(), channel)) { @@ -67,7 +68,7 @@ public class RedissonSubscription extends AbstractSubscription { }); list.add(f); } - for (RFuture future : list) { + for (CompletableFuture future : list) { commandExecutor.syncSubscription(future); } } @@ -81,9 +82,9 @@ public class RedissonSubscription extends AbstractSubscription { @Override protected void doPsubscribe(byte[]... patterns) { - List> list = new ArrayList<>(); + List> list = new ArrayList<>(); for (byte[] channel : patterns) { - RFuture> f = subscribeService.psubscribe(new ChannelName(channel), ByteArrayCodec.INSTANCE, new BaseRedisPubSubListener() { + CompletableFuture> f = subscribeService.psubscribe(new ChannelName(channel), ByteArrayCodec.INSTANCE, new BaseRedisPubSubListener() { @Override public void onPatternMessage(CharSequence pattern, CharSequence ch, Object message) { if (!Arrays.equals(((ChannelName) pattern).getName(), channel)) { @@ -97,7 +98,7 @@ public class RedissonSubscription extends AbstractSubscription { }); list.add(f); } - for (RFuture future : list) { + for (CompletableFuture future : list) { commandExecutor.syncSubscription(future); } } diff --git a/redisson-spring-data/redisson-spring-data-22/src/main/java/org/redisson/spring/data/connection/RedissonReactiveSubscription.java b/redisson-spring-data/redisson-spring-data-22/src/main/java/org/redisson/spring/data/connection/RedissonReactiveSubscription.java index c890ef263..13cba6bbc 100644 --- a/redisson-spring-data/redisson-spring-data-22/src/main/java/org/redisson/spring/data/connection/RedissonReactiveSubscription.java +++ b/redisson-spring-data/redisson-spring-data-22/src/main/java/org/redisson/spring/data/connection/RedissonReactiveSubscription.java @@ -32,10 +32,9 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import java.nio.ByteBuffer; -import java.util.Collection; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Set; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; @@ -98,19 +97,19 @@ public class RedissonReactiveSubscription implements ReactiveSubscription { public Mono subscribe(ByteBuffer... channels) { monosListener.acquire(); return Mono.defer(() -> { - RedissonPromise result = new RedissonPromise<>(); - result.onComplete((r, ex) -> { - monosListener.release(); - }); - CountableListener listener = new CountableListener<>(result, null, channels.length); + List> futures = new ArrayList<>(); for (ByteBuffer channel : channels) { ChannelName cn = toChannelName(channel); - RFuture f = subscribeService.subscribe(ByteArrayCodec.INSTANCE, cn); - f.onComplete((res, e) -> RedissonReactiveSubscription.this.channels.put(cn, res)); - f.onComplete(listener); + CompletableFuture f = subscribeService.subscribe(ByteArrayCodec.INSTANCE, cn); + f = f.whenComplete((res, e) -> RedissonReactiveSubscription.this.channels.put(cn, res)); + futures.add(f); } - return Mono.fromFuture(result); + CompletableFuture future = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); + future = future.whenComplete((r, e) -> { + monosListener.release(); + }); + return Mono.fromFuture(future); }); } @@ -122,18 +121,19 @@ public class RedissonReactiveSubscription implements ReactiveSubscription { public Mono pSubscribe(ByteBuffer... patterns) { monosListener.acquire(); return Mono.defer(() -> { - RedissonPromise result = new RedissonPromise<>(); - result.onComplete((r, ex) -> { - monosListener.release(); - }); - CountableListener listener = new CountableListener<>(result, null, patterns.length); + List> futures = new ArrayList<>(); for (ByteBuffer channel : patterns) { ChannelName cn = toChannelName(channel); - RFuture> f = subscribeService.psubscribe(cn, ByteArrayCodec.INSTANCE); - f.onComplete((res, e) -> RedissonReactiveSubscription.this.patterns.put(cn, res)); - f.onComplete(listener); + CompletableFuture> f = subscribeService.psubscribe(cn, ByteArrayCodec.INSTANCE); + f = f.whenComplete((res, e) -> RedissonReactiveSubscription.this.patterns.put(cn, res)); + futures.add(f); } - return Mono.fromFuture(result); + + CompletableFuture future = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); + future = future.whenComplete((r, e) -> { + monosListener.release(); + }); + return Mono.fromFuture(future); }); } diff --git a/redisson-spring-data/redisson-spring-data-22/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java b/redisson-spring-data/redisson-spring-data-22/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java index b972e7544..d61a2ca2c 100644 --- a/redisson-spring-data/redisson-spring-data-22/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java +++ b/redisson-spring-data/redisson-spring-data-22/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java @@ -32,6 +32,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.concurrent.CompletableFuture; /** * @@ -51,9 +52,9 @@ public class RedissonSubscription extends AbstractSubscription { @Override protected void doSubscribe(byte[]... channels) { - List> list = new ArrayList<>(); + List> list = new ArrayList<>(); for (byte[] channel : channels) { - RFuture f = subscribeService.subscribe(ByteArrayCodec.INSTANCE, new ChannelName(channel), new BaseRedisPubSubListener() { + CompletableFuture f = subscribeService.subscribe(ByteArrayCodec.INSTANCE, new ChannelName(channel), new BaseRedisPubSubListener() { @Override public void onMessage(CharSequence ch, Object message) { if (!Arrays.equals(((ChannelName) ch).getName(), channel)) { @@ -67,7 +68,7 @@ public class RedissonSubscription extends AbstractSubscription { }); list.add(f); } - for (RFuture future : list) { + for (CompletableFuture future : list) { commandExecutor.syncSubscription(future); } } @@ -81,9 +82,9 @@ public class RedissonSubscription extends AbstractSubscription { @Override protected void doPsubscribe(byte[]... patterns) { - List> list = new ArrayList<>(); + List> list = new ArrayList<>(); for (byte[] channel : patterns) { - RFuture> f = subscribeService.psubscribe(new ChannelName(channel), ByteArrayCodec.INSTANCE, new BaseRedisPubSubListener() { + CompletableFuture> f = subscribeService.psubscribe(new ChannelName(channel), ByteArrayCodec.INSTANCE, new BaseRedisPubSubListener() { @Override public void onPatternMessage(CharSequence pattern, CharSequence ch, Object message) { if (!Arrays.equals(((ChannelName) pattern).getName(), channel)) { @@ -97,7 +98,7 @@ public class RedissonSubscription extends AbstractSubscription { }); list.add(f); } - for (RFuture future : list) { + for (CompletableFuture future : list) { commandExecutor.syncSubscription(future); } } diff --git a/redisson-spring-data/redisson-spring-data-23/src/main/java/org/redisson/spring/data/connection/RedissonReactiveSubscription.java b/redisson-spring-data/redisson-spring-data-23/src/main/java/org/redisson/spring/data/connection/RedissonReactiveSubscription.java index c890ef263..13cba6bbc 100644 --- a/redisson-spring-data/redisson-spring-data-23/src/main/java/org/redisson/spring/data/connection/RedissonReactiveSubscription.java +++ b/redisson-spring-data/redisson-spring-data-23/src/main/java/org/redisson/spring/data/connection/RedissonReactiveSubscription.java @@ -32,10 +32,9 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import java.nio.ByteBuffer; -import java.util.Collection; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Set; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; @@ -98,19 +97,19 @@ public class RedissonReactiveSubscription implements ReactiveSubscription { public Mono subscribe(ByteBuffer... channels) { monosListener.acquire(); return Mono.defer(() -> { - RedissonPromise result = new RedissonPromise<>(); - result.onComplete((r, ex) -> { - monosListener.release(); - }); - CountableListener listener = new CountableListener<>(result, null, channels.length); + List> futures = new ArrayList<>(); for (ByteBuffer channel : channels) { ChannelName cn = toChannelName(channel); - RFuture f = subscribeService.subscribe(ByteArrayCodec.INSTANCE, cn); - f.onComplete((res, e) -> RedissonReactiveSubscription.this.channels.put(cn, res)); - f.onComplete(listener); + CompletableFuture f = subscribeService.subscribe(ByteArrayCodec.INSTANCE, cn); + f = f.whenComplete((res, e) -> RedissonReactiveSubscription.this.channels.put(cn, res)); + futures.add(f); } - return Mono.fromFuture(result); + CompletableFuture future = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); + future = future.whenComplete((r, e) -> { + monosListener.release(); + }); + return Mono.fromFuture(future); }); } @@ -122,18 +121,19 @@ public class RedissonReactiveSubscription implements ReactiveSubscription { public Mono pSubscribe(ByteBuffer... patterns) { monosListener.acquire(); return Mono.defer(() -> { - RedissonPromise result = new RedissonPromise<>(); - result.onComplete((r, ex) -> { - monosListener.release(); - }); - CountableListener listener = new CountableListener<>(result, null, patterns.length); + List> futures = new ArrayList<>(); for (ByteBuffer channel : patterns) { ChannelName cn = toChannelName(channel); - RFuture> f = subscribeService.psubscribe(cn, ByteArrayCodec.INSTANCE); - f.onComplete((res, e) -> RedissonReactiveSubscription.this.patterns.put(cn, res)); - f.onComplete(listener); + CompletableFuture> f = subscribeService.psubscribe(cn, ByteArrayCodec.INSTANCE); + f = f.whenComplete((res, e) -> RedissonReactiveSubscription.this.patterns.put(cn, res)); + futures.add(f); } - return Mono.fromFuture(result); + + CompletableFuture future = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); + future = future.whenComplete((r, e) -> { + monosListener.release(); + }); + return Mono.fromFuture(future); }); } diff --git a/redisson-spring-data/redisson-spring-data-23/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java b/redisson-spring-data/redisson-spring-data-23/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java index b972e7544..d61a2ca2c 100644 --- a/redisson-spring-data/redisson-spring-data-23/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java +++ b/redisson-spring-data/redisson-spring-data-23/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java @@ -32,6 +32,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.concurrent.CompletableFuture; /** * @@ -51,9 +52,9 @@ public class RedissonSubscription extends AbstractSubscription { @Override protected void doSubscribe(byte[]... channels) { - List> list = new ArrayList<>(); + List> list = new ArrayList<>(); for (byte[] channel : channels) { - RFuture f = subscribeService.subscribe(ByteArrayCodec.INSTANCE, new ChannelName(channel), new BaseRedisPubSubListener() { + CompletableFuture f = subscribeService.subscribe(ByteArrayCodec.INSTANCE, new ChannelName(channel), new BaseRedisPubSubListener() { @Override public void onMessage(CharSequence ch, Object message) { if (!Arrays.equals(((ChannelName) ch).getName(), channel)) { @@ -67,7 +68,7 @@ public class RedissonSubscription extends AbstractSubscription { }); list.add(f); } - for (RFuture future : list) { + for (CompletableFuture future : list) { commandExecutor.syncSubscription(future); } } @@ -81,9 +82,9 @@ public class RedissonSubscription extends AbstractSubscription { @Override protected void doPsubscribe(byte[]... patterns) { - List> list = new ArrayList<>(); + List> list = new ArrayList<>(); for (byte[] channel : patterns) { - RFuture> f = subscribeService.psubscribe(new ChannelName(channel), ByteArrayCodec.INSTANCE, new BaseRedisPubSubListener() { + CompletableFuture> f = subscribeService.psubscribe(new ChannelName(channel), ByteArrayCodec.INSTANCE, new BaseRedisPubSubListener() { @Override public void onPatternMessage(CharSequence pattern, CharSequence ch, Object message) { if (!Arrays.equals(((ChannelName) pattern).getName(), channel)) { @@ -97,7 +98,7 @@ public class RedissonSubscription extends AbstractSubscription { }); list.add(f); } - for (RFuture future : list) { + for (CompletableFuture future : list) { commandExecutor.syncSubscription(future); } } diff --git a/redisson-spring-data/redisson-spring-data-24/src/main/java/org/redisson/spring/data/connection/RedissonReactiveSubscription.java b/redisson-spring-data/redisson-spring-data-24/src/main/java/org/redisson/spring/data/connection/RedissonReactiveSubscription.java index c890ef263..13cba6bbc 100644 --- a/redisson-spring-data/redisson-spring-data-24/src/main/java/org/redisson/spring/data/connection/RedissonReactiveSubscription.java +++ b/redisson-spring-data/redisson-spring-data-24/src/main/java/org/redisson/spring/data/connection/RedissonReactiveSubscription.java @@ -32,10 +32,9 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import java.nio.ByteBuffer; -import java.util.Collection; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Set; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; @@ -98,19 +97,19 @@ public class RedissonReactiveSubscription implements ReactiveSubscription { public Mono subscribe(ByteBuffer... channels) { monosListener.acquire(); return Mono.defer(() -> { - RedissonPromise result = new RedissonPromise<>(); - result.onComplete((r, ex) -> { - monosListener.release(); - }); - CountableListener listener = new CountableListener<>(result, null, channels.length); + List> futures = new ArrayList<>(); for (ByteBuffer channel : channels) { ChannelName cn = toChannelName(channel); - RFuture f = subscribeService.subscribe(ByteArrayCodec.INSTANCE, cn); - f.onComplete((res, e) -> RedissonReactiveSubscription.this.channels.put(cn, res)); - f.onComplete(listener); + CompletableFuture f = subscribeService.subscribe(ByteArrayCodec.INSTANCE, cn); + f = f.whenComplete((res, e) -> RedissonReactiveSubscription.this.channels.put(cn, res)); + futures.add(f); } - return Mono.fromFuture(result); + CompletableFuture future = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); + future = future.whenComplete((r, e) -> { + monosListener.release(); + }); + return Mono.fromFuture(future); }); } @@ -122,18 +121,19 @@ public class RedissonReactiveSubscription implements ReactiveSubscription { public Mono pSubscribe(ByteBuffer... patterns) { monosListener.acquire(); return Mono.defer(() -> { - RedissonPromise result = new RedissonPromise<>(); - result.onComplete((r, ex) -> { - monosListener.release(); - }); - CountableListener listener = new CountableListener<>(result, null, patterns.length); + List> futures = new ArrayList<>(); for (ByteBuffer channel : patterns) { ChannelName cn = toChannelName(channel); - RFuture> f = subscribeService.psubscribe(cn, ByteArrayCodec.INSTANCE); - f.onComplete((res, e) -> RedissonReactiveSubscription.this.patterns.put(cn, res)); - f.onComplete(listener); + CompletableFuture> f = subscribeService.psubscribe(cn, ByteArrayCodec.INSTANCE); + f = f.whenComplete((res, e) -> RedissonReactiveSubscription.this.patterns.put(cn, res)); + futures.add(f); } - return Mono.fromFuture(result); + + CompletableFuture future = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); + future = future.whenComplete((r, e) -> { + monosListener.release(); + }); + return Mono.fromFuture(future); }); } diff --git a/redisson-spring-data/redisson-spring-data-24/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java b/redisson-spring-data/redisson-spring-data-24/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java index b972e7544..d61a2ca2c 100644 --- a/redisson-spring-data/redisson-spring-data-24/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java +++ b/redisson-spring-data/redisson-spring-data-24/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java @@ -32,6 +32,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.concurrent.CompletableFuture; /** * @@ -51,9 +52,9 @@ public class RedissonSubscription extends AbstractSubscription { @Override protected void doSubscribe(byte[]... channels) { - List> list = new ArrayList<>(); + List> list = new ArrayList<>(); for (byte[] channel : channels) { - RFuture f = subscribeService.subscribe(ByteArrayCodec.INSTANCE, new ChannelName(channel), new BaseRedisPubSubListener() { + CompletableFuture f = subscribeService.subscribe(ByteArrayCodec.INSTANCE, new ChannelName(channel), new BaseRedisPubSubListener() { @Override public void onMessage(CharSequence ch, Object message) { if (!Arrays.equals(((ChannelName) ch).getName(), channel)) { @@ -67,7 +68,7 @@ public class RedissonSubscription extends AbstractSubscription { }); list.add(f); } - for (RFuture future : list) { + for (CompletableFuture future : list) { commandExecutor.syncSubscription(future); } } @@ -81,9 +82,9 @@ public class RedissonSubscription extends AbstractSubscription { @Override protected void doPsubscribe(byte[]... patterns) { - List> list = new ArrayList<>(); + List> list = new ArrayList<>(); for (byte[] channel : patterns) { - RFuture> f = subscribeService.psubscribe(new ChannelName(channel), ByteArrayCodec.INSTANCE, new BaseRedisPubSubListener() { + CompletableFuture> f = subscribeService.psubscribe(new ChannelName(channel), ByteArrayCodec.INSTANCE, new BaseRedisPubSubListener() { @Override public void onPatternMessage(CharSequence pattern, CharSequence ch, Object message) { if (!Arrays.equals(((ChannelName) pattern).getName(), channel)) { @@ -97,7 +98,7 @@ public class RedissonSubscription extends AbstractSubscription { }); list.add(f); } - for (RFuture future : list) { + for (CompletableFuture future : list) { commandExecutor.syncSubscription(future); } } diff --git a/redisson-spring-data/redisson-spring-data-25/src/main/java/org/redisson/spring/data/connection/RedissonReactiveSubscription.java b/redisson-spring-data/redisson-spring-data-25/src/main/java/org/redisson/spring/data/connection/RedissonReactiveSubscription.java index 810d77da3..6d6dda74e 100644 --- a/redisson-spring-data/redisson-spring-data-25/src/main/java/org/redisson/spring/data/connection/RedissonReactiveSubscription.java +++ b/redisson-spring-data/redisson-spring-data-25/src/main/java/org/redisson/spring/data/connection/RedissonReactiveSubscription.java @@ -32,10 +32,9 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import java.nio.ByteBuffer; -import java.util.Collection; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Set; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; @@ -99,19 +98,19 @@ public class RedissonReactiveSubscription implements ReactiveSubscription { public Mono subscribe(ByteBuffer... channels) { monosListener.acquire(); return Mono.defer(() -> { - RedissonPromise result = new RedissonPromise<>(); - result.onComplete((r, ex) -> { - monosListener.release(); - }); - CountableListener listener = new CountableListener<>(result, null, channels.length); + List> futures = new ArrayList<>(); for (ByteBuffer channel : channels) { ChannelName cn = toChannelName(channel); - RFuture f = subscribeService.subscribe(ByteArrayCodec.INSTANCE, cn); - f.onComplete((res, e) -> RedissonReactiveSubscription.this.channels.put(cn, res)); - f.onComplete(listener); + CompletableFuture f = subscribeService.subscribe(ByteArrayCodec.INSTANCE, cn); + f = f.whenComplete((res, e) -> RedissonReactiveSubscription.this.channels.put(cn, res)); + futures.add(f); } - return Mono.fromFuture(result); + CompletableFuture future = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); + future = future.whenComplete((r, e) -> { + monosListener.release(); + }); + return Mono.fromFuture(future); }); } @@ -123,18 +122,19 @@ public class RedissonReactiveSubscription implements ReactiveSubscription { public Mono pSubscribe(ByteBuffer... patterns) { monosListener.acquire(); return Mono.defer(() -> { - RedissonPromise result = new RedissonPromise<>(); - result.onComplete((r, ex) -> { - monosListener.release(); - }); - CountableListener listener = new CountableListener<>(result, null, patterns.length); + List> futures = new ArrayList<>(); for (ByteBuffer channel : patterns) { ChannelName cn = toChannelName(channel); - RFuture> f = subscribeService.psubscribe(cn, ByteArrayCodec.INSTANCE); - f.onComplete((res, e) -> RedissonReactiveSubscription.this.patterns.put(cn, res)); - f.onComplete(listener); + CompletableFuture> f = subscribeService.psubscribe(cn, ByteArrayCodec.INSTANCE); + f = f.whenComplete((res, e) -> RedissonReactiveSubscription.this.patterns.put(cn, res)); + futures.add(f); } - return Mono.fromFuture(result); + + CompletableFuture future = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); + future = future.whenComplete((r, e) -> { + monosListener.release(); + }); + return Mono.fromFuture(future); }); } diff --git a/redisson-spring-data/redisson-spring-data-25/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java b/redisson-spring-data/redisson-spring-data-25/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java index b972e7544..d61a2ca2c 100644 --- a/redisson-spring-data/redisson-spring-data-25/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java +++ b/redisson-spring-data/redisson-spring-data-25/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java @@ -32,6 +32,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.concurrent.CompletableFuture; /** * @@ -51,9 +52,9 @@ public class RedissonSubscription extends AbstractSubscription { @Override protected void doSubscribe(byte[]... channels) { - List> list = new ArrayList<>(); + List> list = new ArrayList<>(); for (byte[] channel : channels) { - RFuture f = subscribeService.subscribe(ByteArrayCodec.INSTANCE, new ChannelName(channel), new BaseRedisPubSubListener() { + CompletableFuture f = subscribeService.subscribe(ByteArrayCodec.INSTANCE, new ChannelName(channel), new BaseRedisPubSubListener() { @Override public void onMessage(CharSequence ch, Object message) { if (!Arrays.equals(((ChannelName) ch).getName(), channel)) { @@ -67,7 +68,7 @@ public class RedissonSubscription extends AbstractSubscription { }); list.add(f); } - for (RFuture future : list) { + for (CompletableFuture future : list) { commandExecutor.syncSubscription(future); } } @@ -81,9 +82,9 @@ public class RedissonSubscription extends AbstractSubscription { @Override protected void doPsubscribe(byte[]... patterns) { - List> list = new ArrayList<>(); + List> list = new ArrayList<>(); for (byte[] channel : patterns) { - RFuture> f = subscribeService.psubscribe(new ChannelName(channel), ByteArrayCodec.INSTANCE, new BaseRedisPubSubListener() { + CompletableFuture> f = subscribeService.psubscribe(new ChannelName(channel), ByteArrayCodec.INSTANCE, new BaseRedisPubSubListener() { @Override public void onPatternMessage(CharSequence pattern, CharSequence ch, Object message) { if (!Arrays.equals(((ChannelName) pattern).getName(), channel)) { @@ -97,7 +98,7 @@ public class RedissonSubscription extends AbstractSubscription { }); list.add(f); } - for (RFuture future : list) { + for (CompletableFuture future : list) { commandExecutor.syncSubscription(future); } } diff --git a/redisson-spring-data/redisson-spring-data-26/src/main/java/org/redisson/spring/data/connection/RedissonReactiveSubscription.java b/redisson-spring-data/redisson-spring-data-26/src/main/java/org/redisson/spring/data/connection/RedissonReactiveSubscription.java index 3d3945fbd..5a6a10fc8 100644 --- a/redisson-spring-data/redisson-spring-data-26/src/main/java/org/redisson/spring/data/connection/RedissonReactiveSubscription.java +++ b/redisson-spring-data/redisson-spring-data-26/src/main/java/org/redisson/spring/data/connection/RedissonReactiveSubscription.java @@ -35,10 +35,9 @@ import reactor.core.publisher.Mono; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; -import java.util.Collection; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Set; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; @@ -127,19 +126,19 @@ public class RedissonReactiveSubscription implements ReactiveSubscription { public Mono subscribe(ByteBuffer... channels) { monosListener.acquire(); return Mono.defer(() -> { - RedissonPromise result = new RedissonPromise<>(); - result.onComplete((r, ex) -> { - monosListener.release(); - }); - CountableListener listener = new CountableListener<>(result, null, channels.length); + List> futures = new ArrayList<>(); for (ByteBuffer channel : channels) { ChannelName cn = toChannelName(channel); - RFuture f = subscribeService.subscribe(ByteArrayCodec.INSTANCE, cn, subscriptionListener); - f.onComplete((res, e) -> RedissonReactiveSubscription.this.channels.put(cn, res)); - f.onComplete(listener); + CompletableFuture f = subscribeService.subscribe(ByteArrayCodec.INSTANCE, cn, subscriptionListener); + f = f.whenComplete((res, e) -> RedissonReactiveSubscription.this.channels.put(cn, res)); + futures.add(f); } - return Mono.fromFuture(result); + CompletableFuture future = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); + future = future.whenComplete((r, e) -> { + monosListener.release(); + }); + return Mono.fromFuture(future); }); } @@ -151,18 +150,19 @@ public class RedissonReactiveSubscription implements ReactiveSubscription { public Mono pSubscribe(ByteBuffer... patterns) { monosListener.acquire(); return Mono.defer(() -> { - RedissonPromise result = new RedissonPromise<>(); - result.onComplete((r, ex) -> { - monosListener.release(); - }); - CountableListener listener = new CountableListener<>(result, null, patterns.length); + List> futures = new ArrayList<>(); for (ByteBuffer channel : patterns) { ChannelName cn = toChannelName(channel); - RFuture> f = subscribeService.psubscribe(cn, ByteArrayCodec.INSTANCE, subscriptionListener); - f.onComplete((res, e) -> RedissonReactiveSubscription.this.patterns.put(cn, res)); - f.onComplete(listener); + CompletableFuture> f = subscribeService.psubscribe(cn, ByteArrayCodec.INSTANCE, subscriptionListener); + f = f.whenComplete((res, e) -> RedissonReactiveSubscription.this.patterns.put(cn, res)); + futures.add(f); } - return Mono.fromFuture(result); + + CompletableFuture future = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); + future = future.whenComplete((r, e) -> { + monosListener.release(); + }); + return Mono.fromFuture(future); }); } diff --git a/redisson-spring-data/redisson-spring-data-26/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java b/redisson-spring-data/redisson-spring-data-26/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java index b972e7544..78fc0753e 100644 --- a/redisson-spring-data/redisson-spring-data-26/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java +++ b/redisson-spring-data/redisson-spring-data-26/src/main/java/org/redisson/spring/data/connection/RedissonSubscription.java @@ -15,13 +15,11 @@ */ package org.redisson.spring.data.connection; -import org.redisson.api.RFuture; import org.redisson.client.BaseRedisPubSubListener; import org.redisson.client.ChannelName; import org.redisson.client.codec.ByteArrayCodec; import org.redisson.client.protocol.pubsub.PubSubType; import org.redisson.command.CommandAsyncExecutor; -import org.redisson.connection.ConnectionManager; import org.redisson.pubsub.PubSubConnectionEntry; import org.redisson.pubsub.PublishSubscribeService; import org.springframework.data.redis.connection.DefaultMessage; @@ -32,6 +30,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.concurrent.CompletableFuture; /** * @@ -51,9 +50,9 @@ public class RedissonSubscription extends AbstractSubscription { @Override protected void doSubscribe(byte[]... channels) { - List> list = new ArrayList<>(); + List> list = new ArrayList<>(); for (byte[] channel : channels) { - RFuture f = subscribeService.subscribe(ByteArrayCodec.INSTANCE, new ChannelName(channel), new BaseRedisPubSubListener() { + CompletableFuture f = subscribeService.subscribe(ByteArrayCodec.INSTANCE, new ChannelName(channel), new BaseRedisPubSubListener() { @Override public void onMessage(CharSequence ch, Object message) { if (!Arrays.equals(((ChannelName) ch).getName(), channel)) { @@ -67,7 +66,7 @@ public class RedissonSubscription extends AbstractSubscription { }); list.add(f); } - for (RFuture future : list) { + for (CompletableFuture future : list) { commandExecutor.syncSubscription(future); } } @@ -81,9 +80,9 @@ public class RedissonSubscription extends AbstractSubscription { @Override protected void doPsubscribe(byte[]... patterns) { - List> list = new ArrayList<>(); + List> list = new ArrayList<>(); for (byte[] channel : patterns) { - RFuture> f = subscribeService.psubscribe(new ChannelName(channel), ByteArrayCodec.INSTANCE, new BaseRedisPubSubListener() { + CompletableFuture> f = subscribeService.psubscribe(new ChannelName(channel), ByteArrayCodec.INSTANCE, new BaseRedisPubSubListener() { @Override public void onPatternMessage(CharSequence pattern, CharSequence ch, Object message) { if (!Arrays.equals(((ChannelName) pattern).getName(), channel)) { @@ -97,7 +96,7 @@ public class RedissonSubscription extends AbstractSubscription { }); list.add(f); } - for (RFuture future : list) { + for (CompletableFuture future : list) { commandExecutor.syncSubscription(future); } } diff --git a/redisson/src/main/java/org/redisson/PubSubEntry.java b/redisson/src/main/java/org/redisson/PubSubEntry.java index 9de8d6768..d4f8033a6 100644 --- a/redisson/src/main/java/org/redisson/PubSubEntry.java +++ b/redisson/src/main/java/org/redisson/PubSubEntry.java @@ -15,7 +15,7 @@ */ package org.redisson; -import org.redisson.misc.RPromise; +import java.util.concurrent.CompletableFuture; /** * @@ -28,6 +28,6 @@ public interface PubSubEntry { int release(); - RPromise getPromise(); + CompletableFuture getPromise(); } diff --git a/redisson/src/main/java/org/redisson/RedissonCountDownLatch.java b/redisson/src/main/java/org/redisson/RedissonCountDownLatch.java index f1fabdfa3..9e4bbdf6c 100644 --- a/redisson/src/main/java/org/redisson/RedissonCountDownLatch.java +++ b/redisson/src/main/java/org/redisson/RedissonCountDownLatch.java @@ -15,15 +15,6 @@ */ package org.redisson; -import java.util.Arrays; -import java.util.concurrent.CancellationException; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.AtomicReference; - import io.netty.util.Timeout; import io.netty.util.TimerTask; import org.redisson.api.RCountDownLatch; @@ -31,10 +22,15 @@ import org.redisson.api.RFuture; import org.redisson.client.codec.LongCodec; import org.redisson.client.protocol.RedisCommands; import org.redisson.command.CommandAsyncExecutor; -import org.redisson.misc.RPromise; -import org.redisson.misc.RedissonPromise; +import org.redisson.misc.CompletableFutureWrapper; import org.redisson.pubsub.CountDownLatchPubSub; +import java.util.Arrays; +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicReference; + /** * Distributed alternative to the {@link java.util.concurrent.CountDownLatch} * @@ -62,66 +58,55 @@ public class RedissonCountDownLatch extends RedissonObject implements RCountDown return; } - RFuture future = subscribe(); + CompletableFuture future = subscribe(); try { commandExecutor.syncSubscriptionInterrupted(future); while (getCount() > 0) { // waiting for open state - future.getNow().getLatch().await(); + commandExecutor.getNow(future).getLatch().await(); } } finally { - unsubscribe(future); + unsubscribe(commandExecutor.getNow(future)); } } - @Override - public RFuture awaitAsync() { - RPromise result = new RedissonPromise<>(); - RFuture countFuture = getCountAsync(); - countFuture.onComplete((r, e) -> { + private CompletableFuture await(RedissonCountDownLatchEntry entry) { + CompletableFuture countFuture = getCountAsync().toCompletableFuture(); + return countFuture.whenComplete((r, e) -> { if (e != null) { - result.tryFailure(e); - return; + unsubscribe(entry); + } + }).thenCompose(r -> { + if (r == 0) { + unsubscribe(entry); + return CompletableFuture.completedFuture(null); } - RFuture subscribeFuture = subscribe(); - subscribeFuture.onComplete((res, ex) -> { - if (ex != null) { - result.tryFailure(ex); - return; - } - - await(result, subscribeFuture); + CompletableFuture future = new CompletableFuture<>(); + entry.addListener(() -> { + await(entry).whenComplete((res, e) -> { + if (e != null) { + future.completeExceptionally(e); + return; + } + future.complete(res); + }); }); + return future; }); - return result; } - private void await(RPromise result, RFuture subscribeFuture) { - if (result.isDone()) { - unsubscribe(subscribeFuture); - return; - } - - RFuture countFuture = getCountAsync(); - countFuture.onComplete((r, e) -> { - if (e != null) { - unsubscribe(subscribeFuture); - result.tryFailure(e); - return; - } - - if (r == 0) { - unsubscribe(subscribeFuture); - result.trySuccess(null); - return; - } - - subscribeFuture.getNow().addListener(() -> { - await(result, subscribeFuture); - }); + @Override + public RFuture awaitAsync() { + CompletableFuture countFuture = getCountAsync().toCompletableFuture(); + CompletableFuture f = countFuture.thenCompose(r -> { + return subscribe(); + }).thenCompose(res -> { + return await(res); }); + + return new CompletableFutureWrapper<>(f); } @Override @@ -131,7 +116,7 @@ public class RedissonCountDownLatch extends RedissonObject implements RCountDown if (getCount() == 0) { return true; } - RFuture promise = subscribe(); + CompletableFuture promise = subscribe(); try { promise.toCompletableFuture().get(time, unit); } catch (ExecutionException | CancellationException e) { @@ -152,99 +137,73 @@ public class RedissonCountDownLatch extends RedissonObject implements RCountDown } current = System.currentTimeMillis(); // waiting for open state - promise.getNow().getLatch().await(remainTime, TimeUnit.MILLISECONDS); + commandExecutor.getNow(promise).getLatch().await(remainTime, TimeUnit.MILLISECONDS); remainTime -= System.currentTimeMillis() - current; } return true; } finally { - unsubscribe(promise); + unsubscribe(commandExecutor.getNow(promise)); } } @Override public RFuture awaitAsync(long waitTime, TimeUnit unit) { - RPromise result = new RedissonPromise<>(); + CompletableFuture result = new CompletableFuture<>(); AtomicLong time = new AtomicLong(unit.toMillis(waitTime)); long currentTime = System.currentTimeMillis(); - RFuture countFuture = getCountAsync(); - countFuture.onComplete((r, e) -> { - if (e != null) { - result.tryFailure(e); - return; - } - + CompletableFuture countFuture = getCountAsync().toCompletableFuture(); + CompletableFuture f = countFuture.thenCompose(r -> { long el = System.currentTimeMillis() - currentTime; time.addAndGet(-el); if (time.get() <= 0) { - result.trySuccess(false); - return; + return CompletableFuture.completedFuture(false); } long current = System.currentTimeMillis(); - AtomicReference futureRef = new AtomicReference<>(); - RFuture subscribeFuture = subscribe(); - subscribeFuture.onComplete((res, ex) -> { - if (ex != null) { - result.tryFailure(ex); - return; - } - - if (futureRef.get() != null) { - futureRef.get().cancel(); - } - + CompletableFuture subscribeFuture = subscribe(); + return subscribeFuture.thenCompose(entry -> { long elapsed = System.currentTimeMillis() - current; time.addAndGet(-elapsed); - await(time, result, subscribeFuture); + return await(time, entry); }); }); - return result; + return new CompletableFutureWrapper<>(f); } - private void await(AtomicLong time, RPromise result, RFuture subscribeFuture) { - if (result.isDone()) { - unsubscribe(subscribeFuture); - return; - } - + private CompletableFuture await(AtomicLong time, RedissonCountDownLatchEntry entry) { if (time.get() <= 0) { - unsubscribe(subscribeFuture); - result.trySuccess(false); - return; + unsubscribe(entry); + return CompletableFuture.completedFuture(false); } long curr = System.currentTimeMillis(); - RFuture countFuture = getCountAsync(); - countFuture.onComplete((r, e) -> { + CompletableFuture countFuture = getCountAsync().toCompletableFuture(); + return countFuture.whenComplete((r, e) -> { if (e != null) { - unsubscribe(subscribeFuture); - result.tryFailure(e); - return; + unsubscribe(entry); } - + }).thenCompose(r -> { if (r == 0) { - unsubscribe(subscribeFuture); - result.trySuccess(true); - return; + unsubscribe(entry); + return CompletableFuture.completedFuture(true); } long el = System.currentTimeMillis() - curr; time.addAndGet(-el); if (time.get() <= 0) { - unsubscribe(subscribeFuture); - result.trySuccess(false); - return; + unsubscribe(entry); + return CompletableFuture.completedFuture(false); } + CompletableFuture future = new CompletableFuture<>(); long current = System.currentTimeMillis(); AtomicBoolean executed = new AtomicBoolean(); - RedissonCountDownLatchEntry entry = subscribeFuture.getNow(); AtomicReference futureRef = new AtomicReference<>(); Runnable listener = () -> { executed.set(true); @@ -255,7 +214,7 @@ public class RedissonCountDownLatch extends RedissonObject implements RCountDown long elapsed = System.currentTimeMillis() - current; time.addAndGet(-elapsed); - await(time, result, subscribeFuture); + commandExecutor.transfer(await(time, entry), future); }; entry.addListener(listener); @@ -267,21 +226,23 @@ public class RedissonCountDownLatch extends RedissonObject implements RCountDown long elapsed = System.currentTimeMillis() - current; time.addAndGet(-elapsed); - await(time, result, subscribeFuture); + commandExecutor.transfer(await(time, entry), future); } } }, time.get(), TimeUnit.MILLISECONDS); futureRef.set(timeoutFuture); } + + return future; }); } - private RFuture subscribe() { + private CompletableFuture subscribe() { return pubSub.subscribe(getEntryName(), getChannelName()); } - private void unsubscribe(RFuture future) { - pubSub.unsubscribe(future.getNow(), getEntryName(), getChannelName()); + private void unsubscribe(RedissonCountDownLatchEntry entry) { + pubSub.unsubscribe(entry, getEntryName(), getChannelName()); } @Override @@ -331,7 +292,7 @@ public class RedissonCountDownLatch extends RedissonObject implements RCountDown + "else " + "return 0 " + "end", - Arrays.asList(getRawName(), getChannelName()), CountDownLatchPubSub.NEW_COUNT_MESSAGE, count); + Arrays.asList(getRawName(), getChannelName()), CountDownLatchPubSub.NEW_COUNT_MESSAGE, count); } @Override @@ -343,7 +304,7 @@ public class RedissonCountDownLatch extends RedissonObject implements RCountDown + "else " + "return 0 " + "end", - Arrays.asList(getRawName(), getChannelName()), CountDownLatchPubSub.NEW_COUNT_MESSAGE); + Arrays.asList(getRawName(), getChannelName()), CountDownLatchPubSub.NEW_COUNT_MESSAGE); } } diff --git a/redisson/src/main/java/org/redisson/RedissonCountDownLatchEntry.java b/redisson/src/main/java/org/redisson/RedissonCountDownLatchEntry.java index d127a05bd..0dcb2ce07 100644 --- a/redisson/src/main/java/org/redisson/RedissonCountDownLatchEntry.java +++ b/redisson/src/main/java/org/redisson/RedissonCountDownLatchEntry.java @@ -15,9 +15,9 @@ */ package org.redisson; -import org.redisson.misc.RPromise; import org.redisson.misc.ReclosableLatch; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentLinkedQueue; public class RedissonCountDownLatchEntry implements PubSubEntry { @@ -25,10 +25,10 @@ public class RedissonCountDownLatchEntry implements PubSubEntry promise; + private final CompletableFuture promise; private final ConcurrentLinkedQueue listeners = new ConcurrentLinkedQueue<>(); - public RedissonCountDownLatchEntry(RPromise promise) { + public RedissonCountDownLatchEntry(CompletableFuture promise) { super(); this.latch = new ReclosableLatch(); this.promise = promise; @@ -42,7 +42,7 @@ public class RedissonCountDownLatchEntry implements PubSubEntry getPromise() { + public CompletableFuture getPromise() { return promise; } diff --git a/redisson/src/main/java/org/redisson/RedissonFairLock.java b/redisson/src/main/java/org/redisson/RedissonFairLock.java index c4f9381be..6f8c7d22a 100644 --- a/redisson/src/main/java/org/redisson/RedissonFairLock.java +++ b/redisson/src/main/java/org/redisson/RedissonFairLock.java @@ -17,6 +17,7 @@ package org.redisson; import java.util.Arrays; import java.util.List; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; @@ -58,14 +59,14 @@ public class RedissonFairLock extends RedissonLock implements RLock { } @Override - protected RFuture subscribe(long threadId) { + protected CompletableFuture subscribe(long threadId) { return pubSub.subscribe(getEntryName() + ":" + threadId, getChannelName() + ":" + getLockName(threadId)); } @Override - protected void unsubscribe(RFuture future, long threadId) { - pubSub.unsubscribe(future.getNow(), getEntryName() + ":" + threadId, + protected void unsubscribe(RedissonLockEntry entry, long threadId) { + pubSub.unsubscribe(entry, getEntryName() + ":" + threadId, getChannelName() + ":" + getLockName(threadId)); } @@ -94,7 +95,7 @@ public class RedissonFairLock extends RedissonLock implements RLock { // remove the thread from the queue and timeouts set "redis.call('zrem', KEYS[2], ARGV[1]);" + "redis.call('lrem', KEYS[1], 0, ARGV[1]);", - Arrays.asList(threadsQueueName, timeoutSetName), + Arrays.asList(threadsQueueName, timeoutSetName), getLockName(threadId), wait); } @@ -335,7 +336,7 @@ public class RedissonFairLock extends RedissonLock implements RLock { "return 1; " + "end; " + "return 0;", - Arrays.asList(getRawName(), threadsQueueName, timeoutSetName, getChannelName()), + Arrays.asList(getRawName(), threadsQueueName, timeoutSetName, getChannelName()), LockPubSub.UNLOCK_MESSAGE, System.currentTimeMillis()); } diff --git a/redisson/src/main/java/org/redisson/RedissonLock.java b/redisson/src/main/java/org/redisson/RedissonLock.java index 03ed9f496..eee4254db 100644 --- a/redisson/src/main/java/org/redisson/RedissonLock.java +++ b/redisson/src/main/java/org/redisson/RedissonLock.java @@ -29,6 +29,7 @@ import org.redisson.pubsub.LockPubSub; import java.util.Arrays; import java.util.Collections; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -102,7 +103,7 @@ public class RedissonLock extends RedissonBaseLock { return; } - RFuture future = subscribe(threadId); + CompletableFuture future = subscribe(threadId); if (interruptibly) { commandExecutor.syncSubscriptionInterrupted(future); } else { @@ -120,23 +121,23 @@ public class RedissonLock extends RedissonBaseLock { // waiting for message if (ttl >= 0) { try { - future.getNow().getLatch().tryAcquire(ttl, TimeUnit.MILLISECONDS); + commandExecutor.getNow(future).getLatch().tryAcquire(ttl, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { if (interruptibly) { throw e; } - future.getNow().getLatch().tryAcquire(ttl, TimeUnit.MILLISECONDS); + commandExecutor.getNow(future).getLatch().tryAcquire(ttl, TimeUnit.MILLISECONDS); } } else { if (interruptibly) { - future.getNow().getLatch().acquire(); + commandExecutor.getNow(future).getLatch().acquire(); } else { - future.getNow().getLatch().acquireUninterruptibly(); + commandExecutor.getNow(future).getLatch().acquireUninterruptibly(); } } } } finally { - unsubscribe(future, threadId); + unsubscribe(commandExecutor.getNow(future), threadId); } // get(lockAsync(leaseTime, unit)); } @@ -235,14 +236,14 @@ public class RedissonLock extends RedissonBaseLock { } current = System.currentTimeMillis(); - RFuture subscribeFuture = subscribe(threadId); + CompletableFuture subscribeFuture = subscribe(threadId); try { subscribeFuture.toCompletableFuture().get(time, TimeUnit.MILLISECONDS); } catch (ExecutionException | TimeoutException e) { if (!subscribeFuture.cancel(false)) { - subscribeFuture.onComplete((res, ex) -> { + subscribeFuture.whenComplete((res, ex) -> { if (ex == null) { - unsubscribe(subscribeFuture, threadId); + unsubscribe(res, threadId); } }); } @@ -274,9 +275,9 @@ public class RedissonLock extends RedissonBaseLock { // waiting for message currentTime = System.currentTimeMillis(); if (ttl >= 0 && ttl < time) { - subscribeFuture.getNow().getLatch().tryAcquire(ttl, TimeUnit.MILLISECONDS); + commandExecutor.getNow(subscribeFuture).getLatch().tryAcquire(ttl, TimeUnit.MILLISECONDS); } else { - subscribeFuture.getNow().getLatch().tryAcquire(time, TimeUnit.MILLISECONDS); + commandExecutor.getNow(subscribeFuture).getLatch().tryAcquire(time, TimeUnit.MILLISECONDS); } time -= System.currentTimeMillis() - currentTime; @@ -286,17 +287,17 @@ public class RedissonLock extends RedissonBaseLock { } } } finally { - unsubscribe(subscribeFuture, threadId); + unsubscribe(commandExecutor.getNow(subscribeFuture), threadId); } // return get(tryLockAsync(waitTime, leaseTime, unit)); } - protected RFuture subscribe(long threadId) { + protected CompletableFuture subscribe(long threadId) { return pubSub.subscribe(getEntryName(), getChannelName()); } - protected void unsubscribe(RFuture future, long threadId) { - pubSub.unsubscribe(future.getNow(), getEntryName(), getChannelName()); + protected void unsubscribe(RedissonLockEntry entry, long threadId) { + pubSub.unsubscribe(entry, getEntryName(), getChannelName()); } @Override @@ -397,14 +398,14 @@ public class RedissonLock extends RedissonBaseLock { return; } - RFuture subscribeFuture = subscribe(currentThreadId); - subscribeFuture.onComplete((res, ex) -> { + CompletableFuture subscribeFuture = subscribe(currentThreadId); + subscribeFuture.whenComplete((res, ex) -> { if (ex != null) { result.tryFailure(ex); return; } - lockAsync(leaseTime, unit, subscribeFuture, result, currentThreadId); + lockAsync(leaseTime, unit, res, result, currentThreadId); }); }); @@ -412,27 +413,26 @@ public class RedissonLock extends RedissonBaseLock { } private void lockAsync(long leaseTime, TimeUnit unit, - RFuture subscribeFuture, RPromise result, long currentThreadId) { + RedissonLockEntry entry, RPromise result, long currentThreadId) { RFuture ttlFuture = tryAcquireAsync(-1, leaseTime, unit, currentThreadId); ttlFuture.onComplete((ttl, e) -> { if (e != null) { - unsubscribe(subscribeFuture, currentThreadId); + unsubscribe(entry, currentThreadId); result.tryFailure(e); return; } // lock acquired if (ttl == null) { - unsubscribe(subscribeFuture, currentThreadId); + unsubscribe(entry, currentThreadId); if (!result.trySuccess(null)) { unlockAsync(currentThreadId); } return; } - RedissonLockEntry entry = subscribeFuture.getNow(); if (entry.getLatch().tryAcquire()) { - lockAsync(leaseTime, unit, subscribeFuture, result, currentThreadId); + lockAsync(leaseTime, unit, entry, result, currentThreadId); } else { // waiting for message AtomicReference futureRef = new AtomicReference(); @@ -440,7 +440,7 @@ public class RedissonLock extends RedissonBaseLock { if (futureRef.get() != null) { futureRef.get().cancel(); } - lockAsync(leaseTime, unit, subscribeFuture, result, currentThreadId); + lockAsync(leaseTime, unit, entry, result, currentThreadId); }; entry.addListener(listener); @@ -450,7 +450,7 @@ public class RedissonLock extends RedissonBaseLock { @Override public void run(Timeout timeout) throws Exception { if (entry.removeListener(listener)) { - lockAsync(leaseTime, unit, subscribeFuture, result, currentThreadId); + lockAsync(leaseTime, unit, entry, result, currentThreadId); } } }, ttl, TimeUnit.MILLISECONDS); @@ -513,8 +513,8 @@ public class RedissonLock extends RedissonBaseLock { long current = System.currentTimeMillis(); AtomicReference futureRef = new AtomicReference(); - RFuture subscribeFuture = subscribe(currentThreadId); - subscribeFuture.onComplete((r, ex) -> { + CompletableFuture subscribeFuture = subscribe(currentThreadId); + subscribeFuture.whenComplete((r, ex) -> { if (ex != null) { result.tryFailure(ex); return; @@ -527,7 +527,7 @@ public class RedissonLock extends RedissonBaseLock { long elapsed = System.currentTimeMillis() - current; time.addAndGet(-elapsed); - tryLockAsync(time, waitTime, leaseTime, unit, subscribeFuture, result, currentThreadId); + tryLockAsync(time, waitTime, leaseTime, unit, r, result, currentThreadId); }); if (!subscribeFuture.isDone()) { Timeout scheduledFuture = commandExecutor.getConnectionManager().newTimeout(new TimerTask() { @@ -558,14 +558,14 @@ public class RedissonLock extends RedissonBaseLock { } private void tryLockAsync(AtomicLong time, long waitTime, long leaseTime, TimeUnit unit, - RFuture subscribeFuture, RPromise result, long currentThreadId) { + RedissonLockEntry entry, RPromise result, long currentThreadId) { if (result.isDone()) { - unsubscribe(subscribeFuture, currentThreadId); + unsubscribe(entry, currentThreadId); return; } if (time.get() <= 0) { - unsubscribe(subscribeFuture, currentThreadId); + unsubscribe(entry, currentThreadId); trySuccessFalse(currentThreadId, result); return; } @@ -574,14 +574,14 @@ public class RedissonLock extends RedissonBaseLock { RFuture ttlFuture = tryAcquireAsync(waitTime, leaseTime, unit, currentThreadId); ttlFuture.onComplete((ttl, e) -> { if (e != null) { - unsubscribe(subscribeFuture, currentThreadId); + unsubscribe(entry, currentThreadId); result.tryFailure(e); return; } // lock acquired if (ttl == null) { - unsubscribe(subscribeFuture, currentThreadId); + unsubscribe(entry, currentThreadId); if (!result.trySuccess(true)) { unlockAsync(currentThreadId); } @@ -592,16 +592,15 @@ public class RedissonLock extends RedissonBaseLock { time.addAndGet(-el); if (time.get() <= 0) { - unsubscribe(subscribeFuture, currentThreadId); + unsubscribe(entry, currentThreadId); trySuccessFalse(currentThreadId, result); return; } // waiting for message long current = System.currentTimeMillis(); - RedissonLockEntry entry = subscribeFuture.getNow(); if (entry.getLatch().tryAcquire()) { - tryLockAsync(time, waitTime, leaseTime, unit, subscribeFuture, result, currentThreadId); + tryLockAsync(time, waitTime, leaseTime, unit, entry, result, currentThreadId); } else { AtomicBoolean executed = new AtomicBoolean(); AtomicReference futureRef = new AtomicReference(); @@ -614,7 +613,7 @@ public class RedissonLock extends RedissonBaseLock { long elapsed = System.currentTimeMillis() - current; time.addAndGet(-elapsed); - tryLockAsync(time, waitTime, leaseTime, unit, subscribeFuture, result, currentThreadId); + tryLockAsync(time, waitTime, leaseTime, unit, entry, result, currentThreadId); }; entry.addListener(listener); @@ -630,7 +629,7 @@ public class RedissonLock extends RedissonBaseLock { long elapsed = System.currentTimeMillis() - current; time.addAndGet(-elapsed); - tryLockAsync(time, waitTime, leaseTime, unit, subscribeFuture, result, currentThreadId); + tryLockAsync(time, waitTime, leaseTime, unit, entry, result, currentThreadId); } } }, t, TimeUnit.MILLISECONDS); diff --git a/redisson/src/main/java/org/redisson/RedissonLockEntry.java b/redisson/src/main/java/org/redisson/RedissonLockEntry.java index cfb1d5c98..7a9d03b7b 100644 --- a/redisson/src/main/java/org/redisson/RedissonLockEntry.java +++ b/redisson/src/main/java/org/redisson/RedissonLockEntry.java @@ -15,11 +15,10 @@ */ package org.redisson; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.Semaphore; -import org.redisson.misc.RPromise; - /** * * @author Nikita Koksharov @@ -30,10 +29,10 @@ public class RedissonLockEntry implements PubSubEntry { private volatile int counter; private final Semaphore latch; - private final RPromise promise; + private final CompletableFuture promise; private final ConcurrentLinkedQueue listeners = new ConcurrentLinkedQueue(); - public RedissonLockEntry(RPromise promise) { + public RedissonLockEntry(CompletableFuture promise) { super(); this.latch = new Semaphore(0); this.promise = promise; @@ -51,7 +50,7 @@ public class RedissonLockEntry implements PubSubEntry { return --counter; } - public RPromise getPromise() { + public CompletableFuture getPromise() { return promise; } diff --git a/redisson/src/main/java/org/redisson/RedissonNode.java b/redisson/src/main/java/org/redisson/RedissonNode.java index cd47f91c3..0085f590a 100644 --- a/redisson/src/main/java/org/redisson/RedissonNode.java +++ b/redisson/src/main/java/org/redisson/RedissonNode.java @@ -17,7 +17,6 @@ package org.redisson; import io.netty.buffer.ByteBufUtil; import org.redisson.api.RExecutorService; -import org.redisson.api.RFuture; import org.redisson.api.RedissonClient; import org.redisson.api.WorkerOptions; import org.redisson.client.RedisConnection; @@ -32,6 +31,7 @@ import java.io.File; import java.io.IOException; import java.net.InetSocketAddress; import java.util.Map.Entry; +import java.util.concurrent.CompletionStage; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; @@ -167,7 +167,7 @@ public final class RedissonNode { private void retrieveAddresses() { ConnectionManager connectionManager = ((Redisson) redisson).getConnectionManager(); for (MasterSlaveEntry entry : connectionManager.getEntrySet()) { - RFuture readFuture = entry.connectionReadOp(null); + CompletionStage readFuture = entry.connectionReadOp(null); RedisConnection readConnection = null; try { readConnection = readFuture.toCompletableFuture().get(connectionManager.getConfig().getConnectTimeout(), TimeUnit.MILLISECONDS); @@ -183,7 +183,7 @@ public final class RedissonNode { return; } - RFuture writeFuture = entry.connectionWriteOp(null); + CompletionStage writeFuture = entry.connectionWriteOp(null); RedisConnection writeConnection = null; try { writeConnection = writeFuture.toCompletableFuture().get(connectionManager.getConfig().getConnectTimeout(), TimeUnit.MILLISECONDS); diff --git a/redisson/src/main/java/org/redisson/RedissonPatternTopic.java b/redisson/src/main/java/org/redisson/RedissonPatternTopic.java index 699995932..80e774242 100644 --- a/redisson/src/main/java/org/redisson/RedissonPatternTopic.java +++ b/redisson/src/main/java/org/redisson/RedissonPatternTopic.java @@ -26,8 +26,7 @@ import org.redisson.client.codec.Codec; import org.redisson.client.protocol.pubsub.PubSubType; import org.redisson.command.CommandAsyncExecutor; import org.redisson.config.MasterSlaveServersConfig; -import org.redisson.misc.RPromise; -import org.redisson.misc.RedissonPromise; +import org.redisson.misc.CompletableFutureWrapper; import org.redisson.pubsub.AsyncSemaphore; import org.redisson.pubsub.PubSubConnectionEntry; import org.redisson.pubsub.PublishSubscribeService; @@ -35,6 +34,7 @@ import org.redisson.pubsub.PublishSubscribeService; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.concurrent.CompletableFuture; /** * Distributed topic implementation. Messages are delivered to all message listeners across Redis cluster. @@ -74,7 +74,7 @@ public class RedissonPatternTopic implements RPatternTopic { } private int addListener(RedisPubSubListener pubSubListener) { - RFuture> future = subscribeService.psubscribe(channelName, codec, pubSubListener); + CompletableFuture> future = subscribeService.psubscribe(channelName, codec, pubSubListener); commandExecutor.syncSubscription(future); return System.identityHashCode(pubSubListener); } @@ -92,17 +92,11 @@ public class RedissonPatternTopic implements RPatternTopic { } private RFuture addListenerAsync(RedisPubSubListener pubSubListener) { - RFuture> future = subscribeService.psubscribe(channelName, codec, pubSubListener); - RPromise result = new RedissonPromise(); - future.onComplete((res, e) -> { - if (e != null) { - result.tryFailure(e); - return; - } - - result.trySuccess(System.identityHashCode(pubSubListener)); + CompletableFuture> future = subscribeService.psubscribe(channelName, codec, pubSubListener); + CompletableFuture f = future.thenApply(res -> { + return System.identityHashCode(pubSubListener); }); - return result; + return new CompletableFutureWrapper<>(f); } protected void acquire(AsyncSemaphore semaphore) { @@ -115,12 +109,13 @@ public class RedissonPatternTopic implements RPatternTopic { @Override public RFuture removeListenerAsync(int listenerId) { - return subscribeService.removeListenerAsync(PubSubType.PUNSUBSCRIBE, channelName, listenerId); + CompletableFuture f = subscribeService.removeListenerAsync(PubSubType.PUNSUBSCRIBE, channelName, listenerId); + return new CompletableFutureWrapper<>(f); } @Override public void removeListener(int listenerId) { - commandExecutor.syncSubscription(removeListenerAsync(listenerId)); + commandExecutor.syncSubscription(removeListenerAsync(listenerId).toCompletableFuture()); } @Override @@ -142,7 +137,7 @@ public class RedissonPatternTopic implements RPatternTopic { @Override public void removeListener(PatternMessageListener listener) { - RFuture future = subscribeService.removeListenerAsync(PubSubType.PUNSUBSCRIBE, channelName, listener); + CompletableFuture future = subscribeService.removeListenerAsync(PubSubType.PUNSUBSCRIBE, channelName, listener); commandExecutor.syncSubscription(future); } diff --git a/redisson/src/main/java/org/redisson/RedissonPermitExpirableSemaphore.java b/redisson/src/main/java/org/redisson/RedissonPermitExpirableSemaphore.java index a6ff38d4b..bd7a4bfd8 100644 --- a/redisson/src/main/java/org/redisson/RedissonPermitExpirableSemaphore.java +++ b/redisson/src/main/java/org/redisson/RedissonPermitExpirableSemaphore.java @@ -15,15 +15,9 @@ */ package org.redisson; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ThreadLocalRandom; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.AtomicReference; - +import io.netty.buffer.ByteBufUtil; +import io.netty.util.Timeout; +import io.netty.util.TimerTask; import org.redisson.api.RFuture; import org.redisson.api.RPermitExpirableSemaphore; import org.redisson.client.codec.LongCodec; @@ -33,9 +27,11 @@ import org.redisson.misc.RPromise; import org.redisson.misc.RedissonPromise; import org.redisson.pubsub.SemaphorePubSub; -import io.netty.buffer.ByteBufUtil; -import io.netty.util.Timeout; -import io.netty.util.TimerTask; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicReference; /** * @@ -91,7 +87,7 @@ public class RedissonPermitExpirableSemaphore extends RedissonExpirable implemen return permitId; } - RFuture future = subscribe(); + CompletableFuture future = subscribe(); commandExecutor.syncSubscriptionInterrupted(future); try { while (true) { @@ -108,13 +104,13 @@ public class RedissonPermitExpirableSemaphore extends RedissonExpirable implemen } if (nearestTimeout != null) { - future.getNow().getLatch().tryAcquire(permits, nearestTimeout, TimeUnit.MILLISECONDS); + commandExecutor.getNow(future).getLatch().tryAcquire(permits, nearestTimeout, TimeUnit.MILLISECONDS); } else { - future.getNow().getLatch().acquire(permits); + commandExecutor.getNow(future).getLatch().acquire(permits); } } } finally { - unsubscribe(future); + unsubscribe(commandExecutor.getNow(future)); } // return get(acquireAsync(permits, ttl, timeUnit)); } @@ -140,27 +136,27 @@ public class RedissonPermitExpirableSemaphore extends RedissonExpirable implemen return; } - RFuture subscribeFuture = subscribe(); - subscribeFuture.onComplete((res, ex) -> { + CompletableFuture subscribeFuture = subscribe(); + subscribeFuture.whenComplete((res, ex) -> { if (ex != null) { result.tryFailure(ex); return; } - acquireAsync(permits, subscribeFuture, result, ttl, timeUnit); + acquireAsync(permits, res, result, ttl, timeUnit); }); }); return result; } - private void tryAcquireAsync(AtomicLong time, int permits, RFuture subscribeFuture, RPromise result, long ttl, TimeUnit timeUnit) { + private void tryAcquireAsync(AtomicLong time, int permits, RedissonLockEntry entry, RPromise result, long ttl, TimeUnit timeUnit) { if (result.isDone()) { - unsubscribe(subscribeFuture); + unsubscribe(entry); return; } if (time.get() <= 0) { - unsubscribe(subscribeFuture); + unsubscribe(entry); result.trySuccess(null); return; } @@ -170,7 +166,7 @@ public class RedissonPermitExpirableSemaphore extends RedissonExpirable implemen RFuture tryAcquireFuture = tryAcquireAsync(permits, timeoutDate); tryAcquireFuture.onComplete((permitId, e) -> { if (e != null) { - unsubscribe(subscribeFuture); + unsubscribe(entry); result.tryFailure(e); return; } @@ -178,7 +174,7 @@ public class RedissonPermitExpirableSemaphore extends RedissonExpirable implemen Long nearestTimeout; if (permitId != null) { if (!permitId.startsWith(":")) { - unsubscribe(subscribeFuture); + unsubscribe(entry); if (!result.trySuccess(permitId)) { releaseAsync(permitId); } @@ -194,16 +190,15 @@ public class RedissonPermitExpirableSemaphore extends RedissonExpirable implemen time.addAndGet(-el); if (time.get() <= 0) { - unsubscribe(subscribeFuture); + unsubscribe(entry); result.trySuccess(null); return; } // waiting for message long current = System.currentTimeMillis(); - RedissonLockEntry entry = subscribeFuture.getNow(); if (entry.getLatch().tryAcquire()) { - tryAcquireAsync(time, permits, subscribeFuture, result, ttl, timeUnit); + tryAcquireAsync(time, permits, entry, result, ttl, timeUnit); } else { AtomicReference waitTimeoutFutureRef = new AtomicReference(); @@ -219,7 +214,7 @@ public class RedissonPermitExpirableSemaphore extends RedissonExpirable implemen long elapsed = System.currentTimeMillis() - current; time.addAndGet(-elapsed); - tryAcquireAsync(time, permits, subscribeFuture, result, ttl, timeUnit); + tryAcquireAsync(time, permits, entry, result, ttl, timeUnit); } }, nearestTimeout, TimeUnit.MILLISECONDS); } else { @@ -239,7 +234,7 @@ public class RedissonPermitExpirableSemaphore extends RedissonExpirable implemen long elapsed = System.currentTimeMillis() - current; time.addAndGet(-elapsed); - tryAcquireAsync(time, permits, subscribeFuture, result, ttl, timeUnit); + tryAcquireAsync(time, permits, entry, result, ttl, timeUnit); }; entry.addListener(listener); @@ -255,7 +250,7 @@ public class RedissonPermitExpirableSemaphore extends RedissonExpirable implemen long elapsed = System.currentTimeMillis() - current; time.addAndGet(-elapsed); - tryAcquireAsync(time, permits, subscribeFuture, result, ttl, timeUnit); + tryAcquireAsync(time, permits, entry, result, ttl, timeUnit); } } }, t, TimeUnit.MILLISECONDS); @@ -265,9 +260,9 @@ public class RedissonPermitExpirableSemaphore extends RedissonExpirable implemen } - private void acquireAsync(int permits, RFuture subscribeFuture, RPromise result, long ttl, TimeUnit timeUnit) { + private void acquireAsync(int permits, RedissonLockEntry entry, RPromise result, long ttl, TimeUnit timeUnit) { if (result.isDone()) { - unsubscribe(subscribeFuture); + unsubscribe(entry); return; } @@ -275,7 +270,7 @@ public class RedissonPermitExpirableSemaphore extends RedissonExpirable implemen RFuture tryAcquireFuture = tryAcquireAsync(permits, timeoutDate); tryAcquireFuture.onComplete((permitId, e) -> { if (e != null) { - unsubscribe(subscribeFuture); + unsubscribe(entry); result.tryFailure(e); return; } @@ -283,7 +278,7 @@ public class RedissonPermitExpirableSemaphore extends RedissonExpirable implemen Long nearestTimeout; if (permitId != null) { if (!permitId.startsWith(":")) { - unsubscribe(subscribeFuture); + unsubscribe(entry); if (!result.trySuccess(permitId)) { releaseAsync(permitId); } @@ -295,16 +290,15 @@ public class RedissonPermitExpirableSemaphore extends RedissonExpirable implemen nearestTimeout = null; } - RedissonLockEntry entry = subscribeFuture.getNow(); if (entry.getLatch().tryAcquire(permits)) { - acquireAsync(permits, subscribeFuture, result, ttl, timeUnit); + acquireAsync(permits, entry, result, ttl, timeUnit); } else { Timeout scheduledFuture; if (nearestTimeout != null) { scheduledFuture = commandExecutor.getConnectionManager().newTimeout(new TimerTask() { @Override public void run(Timeout timeout) throws Exception { - acquireAsync(permits, subscribeFuture, result, ttl, timeUnit); + acquireAsync(permits, entry, result, ttl, timeUnit); } }, nearestTimeout, TimeUnit.MILLISECONDS); } else { @@ -316,7 +310,7 @@ public class RedissonPermitExpirableSemaphore extends RedissonExpirable implemen entry.getLatch().release(); return; } - acquireAsync(permits, subscribeFuture, result, ttl, timeUnit); + acquireAsync(permits, entry, result, ttl, timeUnit); }; entry.addListener(listener); } @@ -343,7 +337,8 @@ public class RedissonPermitExpirableSemaphore extends RedissonExpirable implemen } return nonExpirableTimeout; } - + + @Override public RFuture tryAcquireAsync() { RPromise result = new RedissonPromise(); RFuture future = tryAcquireAsync(1, nonExpirableTimeout); @@ -434,9 +429,10 @@ public class RedissonPermitExpirableSemaphore extends RedissonExpirable implemen } current = System.currentTimeMillis(); - RFuture future = subscribe(); + CompletableFuture future = subscribe(); + RedissonLockEntry entry; try { - future.toCompletableFuture().get(time, TimeUnit.MILLISECONDS); + entry = future.get(time, TimeUnit.MILLISECONDS); } catch (ExecutionException | TimeoutException e) { return null; } @@ -470,9 +466,9 @@ public class RedissonPermitExpirableSemaphore extends RedissonExpirable implemen current = System.currentTimeMillis(); if (nearestTimeout != null) { - future.getNow().getLatch().tryAcquire(permits, Math.min(time, nearestTimeout), TimeUnit.MILLISECONDS); + entry.getLatch().tryAcquire(permits, Math.min(time, nearestTimeout), TimeUnit.MILLISECONDS); } else { - future.getNow().getLatch().tryAcquire(permits, time, TimeUnit.MILLISECONDS); + entry.getLatch().tryAcquire(permits, time, TimeUnit.MILLISECONDS); } long elapsed = System.currentTimeMillis() - current; @@ -482,7 +478,7 @@ public class RedissonPermitExpirableSemaphore extends RedissonExpirable implemen } } } finally { - unsubscribe(future); + unsubscribe(entry); } // return get(tryAcquireAsync(permits, waitTime, ttl, unit)); } @@ -516,8 +512,8 @@ public class RedissonPermitExpirableSemaphore extends RedissonExpirable implemen long current = System.currentTimeMillis(); AtomicReference futureRef = new AtomicReference(); - RFuture subscribeFuture = subscribe(); - subscribeFuture.onComplete((r, ex) -> { + CompletableFuture subscribeFuture = subscribe(); + subscribeFuture.whenComplete((r, ex) -> { if (ex != null) { result.tryFailure(ex); return; @@ -530,7 +526,7 @@ public class RedissonPermitExpirableSemaphore extends RedissonExpirable implemen long elapsed = System.currentTimeMillis() - current; time.addAndGet(-elapsed); - tryAcquireAsync(time, permits, subscribeFuture, result, ttl, timeUnit); + tryAcquireAsync(time, permits, r, result, ttl, timeUnit); }); if (!subscribeFuture.isDone()) { @@ -549,12 +545,12 @@ public class RedissonPermitExpirableSemaphore extends RedissonExpirable implemen return result; } - private RFuture subscribe() { + private CompletableFuture subscribe() { return semaphorePubSub.subscribe(getRawName(), getChannelName()); } - private void unsubscribe(RFuture future) { - semaphorePubSub.unsubscribe(future.getNow(), getRawName(), getChannelName()); + private void unsubscribe(RedissonLockEntry entry) { + semaphorePubSub.unsubscribe(entry, getRawName(), getChannelName()); } @Override diff --git a/redisson/src/main/java/org/redisson/RedissonScript.java b/redisson/src/main/java/org/redisson/RedissonScript.java index 379acd993..97982e0f4 100644 --- a/redisson/src/main/java/org/redisson/RedissonScript.java +++ b/redisson/src/main/java/org/redisson/RedissonScript.java @@ -26,8 +26,6 @@ import org.redisson.command.CommandAsyncExecutor; import org.redisson.connection.MasterSlaveEntry; import org.redisson.connection.NodeSource; import org.redisson.misc.CompletableFutureWrapper; -import org.redisson.misc.RPromise; -import org.redisson.misc.RedissonPromise; import java.util.*; import java.util.concurrent.CompletableFuture; @@ -66,15 +64,13 @@ public class RedissonScript implements RScript { Collection nodes = commandExecutor.getConnectionManager().getEntrySet(); List> futures = new ArrayList<>(); nodes.forEach(e -> { - RPromise promise = new RedissonPromise<>(); - commandExecutor.async(false, new NodeSource(e), codec, RedisCommands.SCRIPT_LOAD, - new Object[]{luaScript}, promise, true, false); + RFuture promise = commandExecutor.async(false, new NodeSource(e), + codec, RedisCommands.SCRIPT_LOAD, new Object[]{luaScript}, true, false); futures.add(promise.toCompletableFuture()); e.getAllEntries().stream().filter(c -> c.getNodeType() == NodeType.SLAVE).forEach(c -> { - RPromise slavePromise = new RedissonPromise<>(); - commandExecutor.async(true, new NodeSource(e, c.getClient()), codec, RedisCommands.SCRIPT_LOAD, - new Object[]{luaScript}, slavePromise, true, false); + RFuture slavePromise = commandExecutor.async(true, new NodeSource(e, c.getClient()), + codec, RedisCommands.SCRIPT_LOAD, new Object[]{luaScript}, true, false); futures.add(slavePromise.toCompletableFuture()); }); }); @@ -157,7 +153,7 @@ public class RedissonScript implements RScript { @Override public RFuture> scriptExistsAsync(final String... shaDigests) { return commandExecutor.writeAllAsync(RedisCommands.SCRIPT_EXISTS, new SlotCallback, List>() { - volatile List result = new ArrayList(shaDigests.length); + volatile List result = new ArrayList<>(shaDigests.length); @Override public synchronized void onSlotResult(List result) { for (int i = 0; i < result.size(); i++) { @@ -170,7 +166,7 @@ public class RedissonScript implements RScript { @Override public List onFinish() { - return new ArrayList(result); + return new ArrayList<>(result); } }, (Object[]) shaDigests); } diff --git a/redisson/src/main/java/org/redisson/RedissonSemaphore.java b/redisson/src/main/java/org/redisson/RedissonSemaphore.java index 03f7b8d4a..f966f7439 100644 --- a/redisson/src/main/java/org/redisson/RedissonSemaphore.java +++ b/redisson/src/main/java/org/redisson/RedissonSemaphore.java @@ -31,10 +31,7 @@ import org.slf4j.LoggerFactory; import java.util.Arrays; import java.util.Collections; -import java.util.concurrent.CancellationException; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; +import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; @@ -83,7 +80,7 @@ public class RedissonSemaphore extends RedissonExpirable implements RSemaphore { return; } - RFuture future = subscribe(); + CompletableFuture future = subscribe(); commandExecutor.syncSubscriptionInterrupted(future); try { while (true) { @@ -91,10 +88,10 @@ public class RedissonSemaphore extends RedissonExpirable implements RSemaphore { return; } - future.getNow().getLatch().acquire(); + commandExecutor.getNow(future).getLatch().acquire(); } } finally { - unsubscribe(future); + unsubscribe(commandExecutor.getNow(future)); } // get(acquireAsync(permits)); } @@ -121,27 +118,27 @@ public class RedissonSemaphore extends RedissonExpirable implements RSemaphore { return; } - RFuture subscribeFuture = subscribe(); - subscribeFuture.onComplete((r, e1) -> { + CompletableFuture subscribeFuture = subscribe(); + subscribeFuture.whenComplete((r, e1) -> { if (e1 != null) { result.tryFailure(e1); return; } - acquireAsync(permits, subscribeFuture, result); + acquireAsync(permits, r, result); }); }); return result; } - private void tryAcquireAsync(AtomicLong time, int permits, RFuture subscribeFuture, RPromise result) { + private void tryAcquireAsync(AtomicLong time, int permits, RedissonLockEntry entry, RPromise result) { if (result.isDone()) { - unsubscribe(subscribeFuture); + unsubscribe(entry); return; } if (time.get() <= 0) { - unsubscribe(subscribeFuture); + unsubscribe(entry); result.trySuccess(false); return; } @@ -150,13 +147,13 @@ public class RedissonSemaphore extends RedissonExpirable implements RSemaphore { RFuture tryAcquireFuture = tryAcquireAsync(permits); tryAcquireFuture.onComplete((res, e) -> { if (e != null) { - unsubscribe(subscribeFuture); + unsubscribe(entry); result.tryFailure(e); return; } if (res) { - unsubscribe(subscribeFuture); + unsubscribe(entry); if (!result.trySuccess(true)) { releaseAsync(permits); } @@ -167,16 +164,15 @@ public class RedissonSemaphore extends RedissonExpirable implements RSemaphore { time.addAndGet(-el); if (time.get() <= 0) { - unsubscribe(subscribeFuture); + unsubscribe(entry); result.trySuccess(false); return; } // waiting for message long current = System.currentTimeMillis(); - RedissonLockEntry entry = subscribeFuture.getNow(); if (entry.getLatch().tryAcquire()) { - tryAcquireAsync(time, permits, subscribeFuture, result); + tryAcquireAsync(time, permits, entry, result); } else { AtomicBoolean executed = new AtomicBoolean(); AtomicReference futureRef = new AtomicReference(); @@ -189,7 +185,7 @@ public class RedissonSemaphore extends RedissonExpirable implements RSemaphore { long elapsed = System.currentTimeMillis() - current; time.addAndGet(-elapsed); - tryAcquireAsync(time, permits, subscribeFuture, result); + tryAcquireAsync(time, permits, entry, result); }; entry.addListener(listener); @@ -202,7 +198,7 @@ public class RedissonSemaphore extends RedissonExpirable implements RSemaphore { long elapsed = System.currentTimeMillis() - current; time.addAndGet(-elapsed); - tryAcquireAsync(time, permits, subscribeFuture, result); + tryAcquireAsync(time, permits, entry, result); } } }, t, TimeUnit.MILLISECONDS); @@ -212,34 +208,33 @@ public class RedissonSemaphore extends RedissonExpirable implements RSemaphore { }); } - private void acquireAsync(int permits, RFuture subscribeFuture, RPromise result) { + private void acquireAsync(int permits, RedissonLockEntry entry, RPromise result) { if (result.isDone()) { - unsubscribe(subscribeFuture); + unsubscribe(entry); return; } RFuture tryAcquireFuture = tryAcquireAsync(permits); tryAcquireFuture.onComplete((res, e) -> { if (e != null) { - unsubscribe(subscribeFuture); + unsubscribe(entry); result.tryFailure(e); return; } if (res) { - unsubscribe(subscribeFuture); + unsubscribe(entry); if (!result.trySuccess(null)) { releaseAsync(permits); } return; } - RedissonLockEntry entry = subscribeFuture.getNow(); if (entry.getLatch().tryAcquire()) { - acquireAsync(permits, subscribeFuture, result); + acquireAsync(permits, entry, result); } else { entry.addListener(() -> { - acquireAsync(permits, subscribeFuture, result); + acquireAsync(permits, entry, result); }); } }); @@ -303,9 +298,10 @@ public class RedissonSemaphore extends RedissonExpirable implements RSemaphore { } current = System.currentTimeMillis(); - RFuture future = subscribe(); + CompletableFuture future = subscribe(); + RedissonLockEntry entry; try { - future.toCompletableFuture().get(time, TimeUnit.MILLISECONDS); + entry = future.get(time, TimeUnit.MILLISECONDS); } catch (ExecutionException | CancellationException | TimeoutException e) { log.debug("unable to subscribe for permits acquisition, permits: {}, name: {}", permits, getName()); return false; @@ -335,7 +331,7 @@ public class RedissonSemaphore extends RedissonExpirable implements RSemaphore { current = System.currentTimeMillis(); log.debug("wait for acquisition, permits: {}, wait-time(ms): {}, name: {}", permits, time, getName()); - future.getNow().getLatch().tryAcquire(time, TimeUnit.MILLISECONDS); + entry.getLatch().tryAcquire(time, TimeUnit.MILLISECONDS); time -= System.currentTimeMillis() - current; if (time <= 0) { @@ -344,7 +340,7 @@ public class RedissonSemaphore extends RedissonExpirable implements RSemaphore { } } } finally { - unsubscribe(future); + unsubscribe(entry); } // return get(tryAcquireAsync(permits, waitTime, unit)); } @@ -378,8 +374,8 @@ public class RedissonSemaphore extends RedissonExpirable implements RSemaphore { long current = System.currentTimeMillis(); AtomicReference futureRef = new AtomicReference(); - RFuture subscribeFuture = subscribe(); - subscribeFuture.onComplete((r, ex) -> { + CompletableFuture subscribeFuture = subscribe(); + subscribeFuture.whenComplete((r, ex) -> { if (ex != null) { result.tryFailure(ex); return; @@ -393,12 +389,12 @@ public class RedissonSemaphore extends RedissonExpirable implements RSemaphore { time.addAndGet(-elapsed); if (time.get() < 0) { - unsubscribe(subscribeFuture); + unsubscribe(r); result.trySuccess(false); return; } - tryAcquireAsync(time, permits, subscribeFuture, result); + tryAcquireAsync(time, permits, r, result); }); if (!subscribeFuture.isDone()) { @@ -416,12 +412,12 @@ public class RedissonSemaphore extends RedissonExpirable implements RSemaphore { return result; } - private RFuture subscribe() { + private CompletableFuture subscribe() { return semaphorePubSub.subscribe(getRawName(), getChannelName()); } - private void unsubscribe(RFuture future) { - semaphorePubSub.unsubscribe(future.getNow(), getRawName(), getChannelName()); + private void unsubscribe(RedissonLockEntry entry) { + semaphorePubSub.unsubscribe(entry, getRawName(), getChannelName()); } @Override diff --git a/redisson/src/main/java/org/redisson/RedissonTopic.java b/redisson/src/main/java/org/redisson/RedissonTopic.java index 658946973..0052f4fea 100644 --- a/redisson/src/main/java/org/redisson/RedissonTopic.java +++ b/redisson/src/main/java/org/redisson/RedissonTopic.java @@ -30,14 +30,14 @@ import org.redisson.client.protocol.RedisCommands; import org.redisson.client.protocol.pubsub.PubSubType; import org.redisson.command.CommandAsyncExecutor; import org.redisson.config.MasterSlaveServersConfig; -import org.redisson.misc.RPromise; -import org.redisson.misc.RedissonPromise; +import org.redisson.misc.CompletableFutureWrapper; import org.redisson.pubsub.AsyncSemaphore; import org.redisson.pubsub.PubSubConnectionEntry; import org.redisson.pubsub.PublishSubscribeService; import java.util.Collections; import java.util.List; +import java.util.concurrent.CompletableFuture; /** * Distributed topic implementation. Messages are delivered to all message listeners across Redis cluster. @@ -104,15 +104,15 @@ public class RedissonTopic implements RTopic { @Override public int addListener(StatusListener listener) { RFuture future = addListenerAsync(listener); - commandExecutor.syncSubscription(future); - return future.getNow(); + commandExecutor.syncSubscription(future.toCompletableFuture()); + return commandExecutor.getNow(future.toCompletableFuture()); }; @Override public int addListener(Class type, MessageListener listener) { RFuture future = addListenerAsync(type, (MessageListener) listener); - commandExecutor.syncSubscription(future); - return future.getNow(); + commandExecutor.syncSubscription(future.toCompletableFuture()); + return commandExecutor.getNow(future.toCompletableFuture()); } @Override @@ -128,22 +128,11 @@ public class RedissonTopic implements RTopic { } protected RFuture addListenerAsync(RedisPubSubListener pubSubListener) { - RFuture future = subscribeService.subscribe(codec, channelName, pubSubListener); - RPromise result = new RedissonPromise<>(); - result.onComplete((res, e) -> { - if (e != null) { - ((RPromise) future).tryFailure(e); - } + CompletableFuture future = subscribeService.subscribe(codec, channelName, pubSubListener); + CompletableFuture f = future.thenApply(res -> { + return System.identityHashCode(pubSubListener); }); - future.onComplete((res, e) -> { - if (e != null) { - result.tryFailure(e); - return; - } - - result.trySuccess(System.identityHashCode(pubSubListener)); - }); - return result; + return new CompletableFutureWrapper<>(f); } @Override @@ -174,22 +163,24 @@ public class RedissonTopic implements RTopic { @Override public void removeListener(MessageListener listener) { RFuture future = removeListenerAsync(listener); - commandExecutor.syncSubscription(future); + commandExecutor.syncSubscription(future.toCompletableFuture()); } @Override public RFuture removeListenerAsync(MessageListener listener) { - return subscribeService.removeListenerAsync(PubSubType.UNSUBSCRIBE, channelName, listener); + CompletableFuture f = subscribeService.removeListenerAsync(PubSubType.UNSUBSCRIBE, channelName, listener); + return new CompletableFutureWrapper<>(f); } @Override public RFuture removeListenerAsync(Integer... listenerIds) { - return subscribeService.removeListenerAsync(PubSubType.UNSUBSCRIBE, channelName, listenerIds); + CompletableFuture f = subscribeService.removeListenerAsync(PubSubType.UNSUBSCRIBE, channelName, listenerIds); + return new CompletableFutureWrapper<>(f); } @Override public void removeListener(Integer... listenerIds) { - commandExecutor.syncSubscription(removeListenerAsync(listenerIds)); + commandExecutor.syncSubscription(removeListenerAsync(listenerIds).toCompletableFuture()); } @Override diff --git a/redisson/src/main/java/org/redisson/client/RedisClient.java b/redisson/src/main/java/org/redisson/client/RedisClient.java index 04cb351e7..b03c92c8e 100644 --- a/redisson/src/main/java/org/redisson/client/RedisClient.java +++ b/redisson/src/main/java/org/redisson/client/RedisClient.java @@ -214,7 +214,7 @@ public final class RedisClient { if (future.isSuccess()) { RedisConnection c = RedisConnection.getFrom(future.channel()); - c.getConnectionPromise().onComplete((res, e) -> { + c.getConnectionPromise().whenComplete((res, e) -> { bootstrap.config().group().execute(new Runnable() { @Override public void run() { @@ -271,7 +271,7 @@ public final class RedisClient { if (future.isSuccess()) { RedisPubSubConnection c = RedisPubSubConnection.getFrom(future.channel()); - c.getConnectionPromise().onComplete((res, e) -> { + c.getConnectionPromise().whenComplete((res, e) -> { pubSubBootstrap.config().group().execute(new Runnable() { @Override public void run() { diff --git a/redisson/src/main/java/org/redisson/client/RedisConnection.java b/redisson/src/main/java/org/redisson/client/RedisConnection.java index cfd530857..07af016d0 100644 --- a/redisson/src/main/java/org/redisson/client/RedisConnection.java +++ b/redisson/src/main/java/org/redisson/client/RedisConnection.java @@ -26,16 +26,18 @@ import org.redisson.client.codec.Codec; import org.redisson.client.handler.CommandsQueue; import org.redisson.client.handler.CommandsQueuePubSub; import org.redisson.client.protocol.*; +import org.redisson.misc.CompletableFutureWrapper; import org.redisson.misc.LogHelper; -import org.redisson.misc.RPromise; import org.redisson.misc.RedissonPromise; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Deque; import java.util.Queue; -import java.util.concurrent.CountDownLatch; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; /** @@ -50,18 +52,18 @@ public class RedisConnection implements RedisCommands { final RedisClient redisClient; - private volatile RPromise fastReconnect; + private volatile CompletableFuture fastReconnect; private volatile boolean closed; volatile Channel channel; - private RPromise connectionPromise; + private CompletableFuture connectionPromise; private long lastUsageTime; private Runnable connectedListener; private Runnable disconnectedListener; private final AtomicInteger usage = new AtomicInteger(); - public RedisConnection(RedisClient redisClient, Channel channel, RPromise connectionPromise) { + public RedisConnection(RedisClient redisClient, Channel channel, CompletableFuture connectionPromise) { this.redisClient = redisClient; this.connectionPromise = connectionPromise; @@ -107,8 +109,8 @@ public class RedisConnection implements RedisCommands { this.disconnectedListener = disconnectedListener; } - public RPromise getConnectionPromise() { - return (RPromise) connectionPromise; + public CompletableFuture getConnectionPromise() { + return (CompletableFuture) connectionPromise; } public static C getFrom(Channel channel) { @@ -179,26 +181,18 @@ public class RedisConnection implements RedisCommands { return redisClient; } - public R await(RFuture future) { - CountDownLatch l = new CountDownLatch(1); - future.onComplete((res, e) -> { - l.countDown(); - }); - + public R await(CompletableFuture future) { try { - if (!l.await(redisClient.getCommandTimeout(), TimeUnit.MILLISECONDS)) { - RPromise promise = (RPromise) future; - RedisTimeoutException ex = new RedisTimeoutException("Command execution timeout for " + redisClient.getAddr()); - promise.tryFailure(ex); - throw ex; - } - if (!future.isSuccess()) { - if (future.cause() instanceof RedisException) { - throw (RedisException) future.cause(); - } - throw new RedisException("Unexpected exception while processing command", future.cause()); + return future.get(redisClient.getCommandTimeout(), TimeUnit.MILLISECONDS); + } catch (ExecutionException e) { + if (e.getCause() instanceof RedisException) { + throw (RedisException) e.getCause(); } - return future.getNow(); + throw new RedisException("Unexpected exception while processing command", e.getCause()); + } catch (TimeoutException e) { + RedisTimeoutException ex = new RedisTimeoutException("Command execution timeout for " + redisClient.getAddr()); + future.completeExceptionally(ex); + throw ex; } catch (InterruptedException e) { Thread.currentThread().interrupt(); return null; @@ -218,7 +212,7 @@ public class RedisConnection implements RedisCommands { } public R sync(Codec encoder, RedisCommand command, Object... params) { - RPromise promise = new RedissonPromise(); + CompletableFuture promise = new CompletableFuture<>(); send(new CommandData(promise, encoder, command, params)); return await(promise); } @@ -236,7 +230,7 @@ public class RedisConnection implements RedisCommands { } public RFuture async(long timeout, Codec encoder, RedisCommand command, Object... params) { - RPromise promise = new RedissonPromise(); + CompletableFuture promise = new CompletableFuture<>(); if (timeout == -1) { timeout = redisClient.getCommandTimeout(); } @@ -249,28 +243,25 @@ public class RedisConnection implements RedisCommands { Timeout scheduledFuture = redisClient.getTimer().newTimeout(t -> { RedisTimeoutException ex = new RedisTimeoutException("Command execution timeout for command: " + LogHelper.toString(command, params) + ", Redis client: " + redisClient); - promise.tryFailure(ex); + promise.completeExceptionally(ex); }, timeout, TimeUnit.MILLISECONDS); - promise.onComplete((res, e) -> { + promise.whenComplete((res, e) -> { scheduledFuture.cancel(); }); - ChannelFuture writeFuture = send(new CommandData(promise, encoder, command, params)); - writeFuture.addListener(new ChannelFutureListener() { - @Override - public void operationComplete(ChannelFuture future) throws Exception { - if (!future.isSuccess()) { - promise.tryFailure(future.cause()); - } + ChannelFuture writeFuture = send(new CommandData<>(promise, encoder, command, params)); + writeFuture.addListener((ChannelFutureListener) future -> { + if (!future.isSuccess()) { + promise.completeExceptionally(future.cause()); } }); - return promise; + return new CompletableFutureWrapper<>(promise); } public CommandData create(Codec encoder, RedisCommand command, Object... params) { - RPromise promise = new RedissonPromise(); - return new CommandData(promise, encoder, command, params); + CompletableFuture promise = new CompletableFuture<>(); + return new CommandData<>(promise, encoder, command, params); } private void setClosed(boolean closed) { @@ -286,7 +277,7 @@ public class RedisConnection implements RedisCommands { } public void clearFastReconnect() { - fastReconnect.trySuccess(null); + fastReconnect.complete(null); fastReconnect = null; } @@ -304,8 +295,8 @@ public class RedisConnection implements RedisCommands { } } - public RFuture forceFastReconnectAsync() { - RedissonPromise promise = new RedissonPromise(); + public CompletableFuture forceFastReconnectAsync() { + CompletableFuture promise = new CompletableFuture(); fastReconnect = promise; close(); return promise; diff --git a/redisson/src/main/java/org/redisson/client/RedisPubSubConnection.java b/redisson/src/main/java/org/redisson/client/RedisPubSubConnection.java index c35ca2715..32cee9814 100644 --- a/redisson/src/main/java/org/redisson/client/RedisPubSubConnection.java +++ b/redisson/src/main/java/org/redisson/client/RedisPubSubConnection.java @@ -15,32 +15,21 @@ */ package org.redisson.client; -import java.util.Collections; -import java.util.HashSet; -import java.util.Map; -import java.util.Queue; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentLinkedQueue; - +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.util.concurrent.Future; +import io.netty.util.concurrent.FutureListener; import org.redisson.client.codec.Codec; import org.redisson.client.protocol.CommandData; import org.redisson.client.protocol.RedisCommand; import org.redisson.client.protocol.RedisCommands; import org.redisson.client.protocol.decoder.MultiDecoder; -import org.redisson.client.protocol.pubsub.PubSubMessage; -import org.redisson.client.protocol.pubsub.PubSubMessageDecoder; -import org.redisson.client.protocol.pubsub.PubSubPatternMessage; -import org.redisson.client.protocol.pubsub.PubSubPatternMessageDecoder; -import org.redisson.client.protocol.pubsub.PubSubStatusMessage; -import org.redisson.client.protocol.pubsub.PubSubType; -import org.redisson.misc.RPromise; -import org.redisson.misc.RedissonPromise; +import org.redisson.client.protocol.pubsub.*; -import io.netty.channel.Channel; -import io.netty.channel.ChannelFuture; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.FutureListener; +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; /** * @@ -55,7 +44,7 @@ public class RedisPubSubConnection extends RedisConnection { final Set unsubscibedChannels = new HashSet(); final Set punsubscibedChannels = new HashSet(); - public RedisPubSubConnection(RedisClient redisClient, Channel channel, RPromise connectionPromise) { + public RedisPubSubConnection(RedisClient redisClient, Channel channel, CompletableFuture connectionPromise) { super(redisClient, channel, connectionPromise); } @@ -169,8 +158,8 @@ public class RedisPubSubConnection extends RedisConnection { } private ChannelFuture async(MultiDecoder messageDecoder, RedisCommand command, Object... params) { - RPromise promise = new RedissonPromise(); - return channel.writeAndFlush(new CommandData(promise, messageDecoder, null, command, params)); + CompletableFuture promise = new CompletableFuture<>(); + return channel.writeAndFlush(new CommandData<>(promise, messageDecoder, null, command, params)); } public Map getChannels() { diff --git a/redisson/src/main/java/org/redisson/client/SubscribeListener.java b/redisson/src/main/java/org/redisson/client/SubscribeListener.java index 1dd70ccf3..22f236683 100644 --- a/redisson/src/main/java/org/redisson/client/SubscribeListener.java +++ b/redisson/src/main/java/org/redisson/client/SubscribeListener.java @@ -15,10 +15,9 @@ */ package org.redisson.client; -import org.redisson.api.RFuture; import org.redisson.client.protocol.pubsub.PubSubType; -import org.redisson.misc.RPromise; -import org.redisson.misc.RedissonPromise; + +import java.util.concurrent.CompletableFuture; /** * @@ -27,7 +26,7 @@ import org.redisson.misc.RedissonPromise; */ public class SubscribeListener extends BaseRedisPubSubListener { - private final RPromise promise = new RedissonPromise<>(); + private final CompletableFuture promise = new CompletableFuture<>(); private final ChannelName name; private final PubSubType type; @@ -40,12 +39,12 @@ public class SubscribeListener extends BaseRedisPubSubListener { @Override public boolean onStatus(PubSubType type, CharSequence channel) { if (name.equals(channel) && this.type.equals(type)) { - promise.trySuccess(null); + promise.complete(null); } return true; } - public RFuture getSuccessFuture() { + public CompletableFuture getSuccessFuture() { return promise; } 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 08fdd9d85..6463a3c6d 100644 --- a/redisson/src/main/java/org/redisson/client/handler/BaseConnectionHandler.java +++ b/redisson/src/main/java/org/redisson/client/handler/BaseConnectionHandler.java @@ -15,23 +15,21 @@ */ package org.redisson.client.handler; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; - +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 org.redisson.misc.RPromise; -import org.redisson.misc.RedissonPromise; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInboundHandlerAdapter; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; /** * @@ -41,7 +39,7 @@ import io.netty.channel.ChannelInboundHandlerAdapter; public abstract class BaseConnectionHandler extends ChannelInboundHandlerAdapter { final RedisClient redisClient; - final RPromise connectionPromise = new RedissonPromise(); + final CompletableFuture connectionPromise = new CompletableFuture(); C connection; public BaseConnectionHandler(RedisClient redisClient) { @@ -92,7 +90,7 @@ public abstract class BaseConnectionHandler extends C if (futures.isEmpty()) { ctx.fireChannelActive(); - connectionPromise.trySuccess(connection); + connectionPromise.complete(connection); return; } @@ -110,12 +108,12 @@ public abstract class BaseConnectionHandler extends C return; } connection.closeAsync(); - connectionPromise.tryFailure(e); + connectionPromise.completeExceptionally(e); return; } if (commandsCounter.decrementAndGet() == 0) { ctx.fireChannelActive(); - connectionPromise.trySuccess(connection); + connectionPromise.complete(connection); } }); } 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 82571db55..d5cb4bc2a 100644 --- a/redisson/src/main/java/org/redisson/client/handler/CommandDecoder.java +++ b/redisson/src/main/java/org/redisson/client/handler/CommandDecoder.java @@ -41,13 +41,13 @@ import org.redisson.client.codec.StringCodec; import org.redisson.client.protocol.*; import org.redisson.client.protocol.decoder.MultiDecoder; import org.redisson.misc.LogHelper; -import org.redisson.misc.RPromise; import org.redisson.misc.RedisURI; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.*; +import java.util.concurrent.CompletableFuture; /** * Redis protocol command decoder @@ -211,7 +211,7 @@ public class CommandDecoder extends ReplayingDecoder { } catch (Exception e) { in.readerIndex(endIndex); sendNext(channel); - commands.getPromise().tryFailure(e); + commands.getPromise().completeExceptionally(e); throw e; } } else { @@ -267,13 +267,13 @@ public class CommandDecoder extends ReplayingDecoder { } } } - + decode(in, commandData, null, channel, skipConvertor, commandsData); if (commandData != null && RedisCommands.EXEC.getName().equals(commandData.getCommand().getName()) - && commandData.getPromise().isSuccess()) { - List objects = (List) commandData.getPromise().getNow(); + && (commandData.getPromise().isDone() && !commandData.getPromise().isCompletedExceptionally())) { + List objects = (List) commandData.getPromise().getNow(null); Iterator iter = objects.iterator(); boolean multiFound = false; for (CommandData command : commandBatch.getCommands()) { @@ -311,11 +311,11 @@ public class CommandDecoder extends ReplayingDecoder { } if (commandBatch.isSkipResult() || i == commandBatch.getCommands().size()) { - RPromise promise = commandBatch.getPromise(); + CompletableFuture promise = commandBatch.getPromise(); if (error != null) { - promise.tryFailure(error); + promise.completeExceptionally(error); } else { - promise.trySuccess(null); + promise.complete(null); } sendNext(channel); @@ -418,7 +418,7 @@ public class CommandDecoder extends ReplayingDecoder { } CommandData commandData = (CommandData) commandsData.get(i+suffix); decode(in, commandData, respParts, channel, skipConvertor, commandsData); - if (commandData.getPromise().isDone() && !commandData.getPromise().isSuccess()) { + if (commandData.getPromise().isDone() && commandData.getPromise().isCompletedExceptionally()) { data.tryFailure(commandData.cause()); } } @@ -457,7 +457,7 @@ public class CommandDecoder extends ReplayingDecoder { protected void completeResponse(CommandData data, Object result) { if (data != null) { - data.getPromise().trySuccess(result); + data.getPromise().complete(result); } } diff --git a/redisson/src/main/java/org/redisson/client/handler/ConnectionWatchdog.java b/redisson/src/main/java/org/redisson/client/handler/ConnectionWatchdog.java index 71b31ea34..2104e20c7 100644 --- a/redisson/src/main/java/org/redisson/client/handler/ConnectionWatchdog.java +++ b/redisson/src/main/java/org/redisson/client/handler/ConnectionWatchdog.java @@ -135,7 +135,7 @@ public class ConnectionWatchdog extends ChannelInboundHandlerAdapter { connection.getRedisClient().getAddr(), channel.localAddress(), channel.remoteAddress()); } else { RedisConnection c = RedisConnection.getFrom(channel); - c.getConnectionPromise().onComplete((res, e) -> { + c.getConnectionPromise().whenComplete((res, e) -> { if (e == null) { if (connection.getRedisClient().isShutdown() || connection.isClosed()) { 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 2e5c69803..b008a1522 100644 --- a/redisson/src/main/java/org/redisson/client/handler/PingConnectionHandler.java +++ b/redisson/src/main/java/org/redisson/client/handler/PingConnectionHandler.java @@ -47,7 +47,7 @@ public class PingConnectionHandler extends ChannelInboundHandlerAdapter { @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { RedisConnection connection = RedisConnection.getFrom(ctx.channel()); - connection.getConnectionPromise().onComplete((res, e) -> { + connection.getConnectionPromise().whenComplete((res, e) -> { if (e == null) { sendPing(ctx); } diff --git a/redisson/src/main/java/org/redisson/client/handler/RedisChannelInitializer.java b/redisson/src/main/java/org/redisson/client/handler/RedisChannelInitializer.java index 3177a18a1..21bd8495b 100644 --- a/redisson/src/main/java/org/redisson/client/handler/RedisChannelInitializer.java +++ b/redisson/src/main/java/org/redisson/client/handler/RedisChannelInitializer.java @@ -198,7 +198,7 @@ public class RedisChannelInitializer extends ChannelInitializer { } else { RedisConnection connection = RedisConnection.getFrom(ctx.channel()); connection.closeAsync(); - connection.getConnectionPromise().tryFailure(e.cause()); + connection.getConnectionPromise().completeExceptionally(e.cause()); } } diff --git a/redisson/src/main/java/org/redisson/client/protocol/BatchCommandData.java b/redisson/src/main/java/org/redisson/client/protocol/BatchCommandData.java index d5ddc5290..57edd7f06 100644 --- a/redisson/src/main/java/org/redisson/client/protocol/BatchCommandData.java +++ b/redisson/src/main/java/org/redisson/client/protocol/BatchCommandData.java @@ -15,13 +15,12 @@ */ package org.redisson.client.protocol; -import java.util.concurrent.atomic.AtomicReference; - import org.redisson.client.RedisRedirectException; import org.redisson.client.codec.Codec; import org.redisson.client.codec.StringCodec; -import org.redisson.misc.RPromise; -import org.redisson.misc.RedissonPromise; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.atomic.AtomicReference; /** * @@ -36,10 +35,10 @@ public class BatchCommandData extends CommandData implements Compara private final AtomicReference redirectError = new AtomicReference(); public BatchCommandData(RedisCommand command, Object[] params, int index) { - this(new RedissonPromise(), StringCodec.INSTANCE, command, params, index); + this(new CompletableFuture<>(), StringCodec.INSTANCE, command, params, index); } - public BatchCommandData(RPromise promise, Codec codec, RedisCommand command, Object[] params, int index) { + public BatchCommandData(CompletableFuture promise, Codec codec, RedisCommand command, Object[] params, int index) { super(promise, codec, command, params); this.index = index; } diff --git a/redisson/src/main/java/org/redisson/client/protocol/CommandData.java b/redisson/src/main/java/org/redisson/client/protocol/CommandData.java index 166a24f81..be4cfeb35 100644 --- a/redisson/src/main/java/org/redisson/client/protocol/CommandData.java +++ b/redisson/src/main/java/org/redisson/client/protocol/CommandData.java @@ -15,13 +15,14 @@ */ package org.redisson.client.protocol; -import java.util.Collections; -import java.util.List; - import org.redisson.client.codec.Codec; import org.redisson.client.protocol.decoder.MultiDecoder; import org.redisson.misc.LogHelper; -import org.redisson.misc.RPromise; + +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; /** * @@ -32,17 +33,17 @@ import org.redisson.misc.RPromise; */ public class CommandData implements QueueCommand { - final RPromise promise; + final CompletableFuture promise; final RedisCommand command; final Object[] params; final Codec codec; final MultiDecoder messageDecoder; - public CommandData(RPromise promise, Codec codec, RedisCommand command, Object[] params) { + public CommandData(CompletableFuture promise, Codec codec, RedisCommand command, Object[] params) { this(promise, null, codec, command, params); } - public CommandData(RPromise promise, MultiDecoder messageDecoder, Codec codec, RedisCommand command, Object[] params) { + public CommandData(CompletableFuture promise, MultiDecoder messageDecoder, Codec codec, RedisCommand command, Object[] params) { this.promise = promise; this.command = command; this.params = params; @@ -62,20 +63,25 @@ public class CommandData implements QueueCommand { return messageDecoder; } - public RPromise getPromise() { + public CompletableFuture getPromise() { return promise; } public Throwable cause() { - return promise.cause(); + try { + promise.getNow(null); + return null; + } catch (CompletionException e) { + return e.getCause(); + } } public boolean isSuccess() { - return promise.isSuccess(); + return promise.isDone() && !promise.isCompletedExceptionally(); } public boolean tryFailure(Throwable cause) { - return promise.tryFailure(cause); + return promise.completeExceptionally(cause); } public Codec getCodec() { diff --git a/redisson/src/main/java/org/redisson/client/protocol/CommandsData.java b/redisson/src/main/java/org/redisson/client/protocol/CommandsData.java index c08dffd47..503c8dbde 100644 --- a/redisson/src/main/java/org/redisson/client/protocol/CommandsData.java +++ b/redisson/src/main/java/org/redisson/client/protocol/CommandsData.java @@ -17,8 +17,7 @@ package org.redisson.client.protocol; import java.util.ArrayList; import java.util.List; - -import org.redisson.misc.RPromise; +import java.util.concurrent.CompletableFuture; /** * @@ -29,21 +28,21 @@ public class CommandsData implements QueueCommand { private final List> commands; private final List> attachedCommands; - private final RPromise promise; + private final CompletableFuture promise; private final boolean skipResult; private final boolean atomic; private final boolean queued; private final boolean syncSlaves; - public CommandsData(RPromise promise, List> commands, boolean queued, boolean syncSlaves) { + public CommandsData(CompletableFuture promise, List> commands, boolean queued, boolean syncSlaves) { this(promise, commands, null, false, false, queued, syncSlaves); } - public CommandsData(RPromise promise, List> commands, boolean skipResult, boolean atomic, boolean queued, boolean syncSlaves) { + public CommandsData(CompletableFuture promise, List> commands, boolean skipResult, boolean atomic, boolean queued, boolean syncSlaves) { this(promise, commands, null, skipResult, atomic, queued, syncSlaves); } - public CommandsData(RPromise promise, List> commands, List> attachedCommands, + public CommandsData(CompletableFuture promise, List> commands, List> attachedCommands, boolean skipResult, boolean atomic, boolean queued, boolean syncSlaves) { super(); this.promise = promise; @@ -59,7 +58,7 @@ public class CommandsData implements QueueCommand { return syncSlaves; } - public RPromise getPromise() { + public CompletableFuture getPromise() { return promise; } @@ -96,7 +95,7 @@ public class CommandsData implements QueueCommand { @Override public boolean tryFailure(Throwable cause) { - return promise.tryFailure(cause); + return promise.completeExceptionally(cause); } @Override diff --git a/redisson/src/main/java/org/redisson/command/BaseRedisBatchExecutor.java b/redisson/src/main/java/org/redisson/command/BaseRedisBatchExecutor.java index 536e907f0..1a0f62bd3 100644 --- a/redisson/src/main/java/org/redisson/command/BaseRedisBatchExecutor.java +++ b/redisson/src/main/java/org/redisson/command/BaseRedisBatchExecutor.java @@ -15,10 +15,6 @@ */ package org.redisson.command; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; - import org.redisson.api.BatchOptions; import org.redisson.client.codec.Codec; import org.redisson.client.protocol.BatchCommandData; @@ -28,7 +24,11 @@ import org.redisson.connection.ConnectionManager; import org.redisson.connection.MasterSlaveEntry; import org.redisson.connection.NodeSource; import org.redisson.liveobject.core.RedissonObjectBuilder; -import org.redisson.misc.RPromise; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; /** * @@ -47,7 +47,7 @@ public class BaseRedisBatchExecutor extends RedisExecutor { @SuppressWarnings("ParameterNumber") public BaseRedisBatchExecutor(boolean readOnlyMode, NodeSource source, Codec codec, RedisCommand command, - Object[] params, RPromise mainPromise, boolean ignoreRedirect, + Object[] params, CompletableFuture mainPromise, boolean ignoreRedirect, ConnectionManager connectionManager, RedissonObjectBuilder objectBuilder, ConcurrentMap commands, BatchOptions options, AtomicInteger index, AtomicBoolean executed, RedissonObjectBuilder.ReferenceType referenceType, diff --git a/redisson/src/main/java/org/redisson/command/BatchPromise.java b/redisson/src/main/java/org/redisson/command/BatchPromise.java index 5784a0e07..a397e3e03 100644 --- a/redisson/src/main/java/org/redisson/command/BatchPromise.java +++ b/redisson/src/main/java/org/redisson/command/BatchPromise.java @@ -15,28 +15,22 @@ */ package org.redisson.command; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.redisson.api.RFuture; -import org.redisson.misc.RPromise; -import org.redisson.misc.RedissonPromise; +import java.util.concurrent.CompletableFuture; /** * * @author Nikita Koksharov * */ -public class BatchPromise extends RedissonPromise { +public class BatchPromise extends CompletableFuture { - private final AtomicBoolean executed; - private final RFuture sentPromise = new RedissonPromise(); + private final CompletableFuture sentPromise = new CompletableFuture<>(); - public BatchPromise(AtomicBoolean executed) { + public BatchPromise() { super(); - this.executed = executed; } - public RFuture getSentPromise() { + public CompletableFuture getSentPromise() { return sentPromise; } @@ -44,21 +38,5 @@ public class BatchPromise extends RedissonPromise { public boolean cancel(boolean mayInterruptIfRunning) { return false; } - - @Override - public RPromise sync() throws InterruptedException { - if (executed.get()) { - return super.sync(); - } - return (RPromise) sentPromise.sync(); - } - - @Override - public RPromise syncUninterruptibly() { - if (executed.get()) { - return super.syncUninterruptibly(); - } - return (RPromise) sentPromise.syncUninterruptibly(); - } - + } diff --git a/redisson/src/main/java/org/redisson/command/CommandAsyncExecutor.java b/redisson/src/main/java/org/redisson/command/CommandAsyncExecutor.java index 781784af7..85ee16195 100644 --- a/redisson/src/main/java/org/redisson/command/CommandAsyncExecutor.java +++ b/redisson/src/main/java/org/redisson/command/CommandAsyncExecutor.java @@ -26,10 +26,10 @@ import org.redisson.connection.ConnectionManager; import org.redisson.connection.MasterSlaveEntry; import org.redisson.connection.NodeSource; import org.redisson.liveobject.core.RedissonObjectBuilder; -import org.redisson.misc.RPromise; import java.util.Collection; import java.util.List; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; /** @@ -45,9 +45,13 @@ public interface CommandAsyncExecutor { RedisException convertException(ExecutionException e); - void syncSubscription(RFuture future); + void syncSubscription(CompletableFuture future); - void syncSubscriptionInterrupted(RFuture future) throws InterruptedException; + void syncSubscriptionInterrupted(CompletableFuture future) throws InterruptedException; + + void transfer(CompletableFuture future1, CompletableFuture future2); + + V getNow(CompletableFuture future); V get(RFuture future); @@ -111,9 +115,8 @@ public interface CommandAsyncExecutor { RFuture readRandomAsync(MasterSlaveEntry entry, Codec codec, RedisCommand command, Object... params); - void async(boolean readOnlyMode, NodeSource source, Codec codec, - RedisCommand command, Object[] params, RPromise mainPromise, - boolean ignoreRedirect, boolean noRetry); + RFuture async(boolean readOnlyMode, NodeSource source, Codec codec, + RedisCommand command, Object[] params, boolean ignoreRedirect, boolean noRetry); RFuture pollFromAnyAsync(String name, Codec codec, RedisCommand command, long secondsTimeout, String... queueNames); diff --git a/redisson/src/main/java/org/redisson/command/CommandAsyncService.java b/redisson/src/main/java/org/redisson/command/CommandAsyncService.java index 14667ea74..a39d39ece 100644 --- a/redisson/src/main/java/org/redisson/command/CommandAsyncService.java +++ b/redisson/src/main/java/org/redisson/command/CommandAsyncService.java @@ -36,6 +36,7 @@ import org.redisson.connection.ConnectionManager; import org.redisson.connection.MasterSlaveEntry; import org.redisson.connection.NodeSource; import org.redisson.liveobject.core.RedissonObjectBuilder; +import org.redisson.misc.CompletableFutureWrapper; import org.redisson.misc.RPromise; import org.redisson.misc.RedissonPromise; import org.slf4j.Logger; @@ -81,11 +82,11 @@ public class CommandAsyncService implements CommandAsyncExecutor { } @Override - public void syncSubscription(RFuture future) { + public void syncSubscription(CompletableFuture future) { MasterSlaveServersConfig config = connectionManager.getConfig(); int timeout = config.getTimeout() + config.getRetryInterval() * config.getRetryAttempts(); try { - future.toCompletableFuture().get(timeout, TimeUnit.MILLISECONDS); + future.get(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } catch (CancellationException e) { @@ -93,25 +94,46 @@ public class CommandAsyncService implements CommandAsyncExecutor { } catch (ExecutionException e) { throw (RuntimeException) e.getCause(); } catch (TimeoutException e) { - ((RPromise) future).tryFailure(new RedisTimeoutException("Subscribe timeout: (" + timeout + "ms). Increase 'subscriptionsPerConnection' and/or 'subscriptionConnectionPoolSize' parameters.")); + future.completeExceptionally(new RedisTimeoutException("Subscribe timeout: (" + timeout + "ms). Increase 'subscriptionsPerConnection' and/or 'subscriptionConnectionPoolSize' parameters.")); } } @Override - public void syncSubscriptionInterrupted(RFuture future) throws InterruptedException { + public void syncSubscriptionInterrupted(CompletableFuture future) throws InterruptedException { MasterSlaveServersConfig config = connectionManager.getConfig(); int timeout = config.getTimeout() + config.getRetryInterval() * config.getRetryAttempts(); try { - future.toCompletableFuture().get(timeout, TimeUnit.MILLISECONDS); + future.get(timeout, TimeUnit.MILLISECONDS); } catch (CancellationException e) { // skip } catch (ExecutionException e) { throw (RuntimeException) e.getCause(); } catch (TimeoutException e) { - ((RPromise) future).tryFailure(new RedisTimeoutException("Subscribe timeout: (" + timeout + "ms). Increase 'subscriptionsPerConnection' and/or 'subscriptionConnectionPoolSize' parameters.")); + future.completeExceptionally(new RedisTimeoutException("Subscribe timeout: (" + timeout + "ms). Increase 'subscriptionsPerConnection' and/or 'subscriptionConnectionPoolSize' parameters.")); } } + @Override + public V getNow(CompletableFuture future) { + try { + return future.getNow(null); + } catch (Exception e) { + return null; + } + } + + @Override + public void transfer(CompletableFuture future1, CompletableFuture future2) { + future1.whenComplete((res, e) -> { + if (e != null) { + future2.completeExceptionally(e); + return; + } + + future2.complete(res); + }); + } + @Override public V get(RFuture future) { if (Thread.currentThread().getName().startsWith("redisson-netty")) { @@ -134,44 +156,36 @@ public class CommandAsyncService implements CommandAsyncExecutor { try { return future.toCompletableFuture().get(); } catch (InterruptedException e) { - ((RPromise) future).tryFailure(e); + future.toCompletableFuture().completeExceptionally(e); throw e; } catch (ExecutionException e) { throw convertException(e); } } - protected RPromise createPromise() { - return new RedissonPromise(); + protected CompletableFuture createPromise() { + return new CompletableFuture(); } @Override public RFuture readAsync(RedisClient client, MasterSlaveEntry entry, Codec codec, RedisCommand command, Object... params) { - RPromise mainPromise = createPromise(); - async(true, new NodeSource(entry, client), codec, command, params, mainPromise, false, false); - return mainPromise; + return async(true, new NodeSource(entry, client), codec, command, params, false, false); } @Override public RFuture readAsync(RedisClient client, String name, Codec codec, RedisCommand command, Object... params) { - RPromise mainPromise = createPromise(); int slot = connectionManager.calcSlot(name); - async(true, new NodeSource(slot, client), codec, command, params, mainPromise, false, false); - return mainPromise; + return async(true, new NodeSource(slot, client), codec, command, params, false, false); } public RFuture readAsync(RedisClient client, byte[] key, Codec codec, RedisCommand command, Object... params) { - RPromise mainPromise = createPromise(); int slot = connectionManager.calcSlot(key); - async(true, new NodeSource(slot, client), codec, command, params, mainPromise, false, false); - return mainPromise; + return async(true, new NodeSource(slot, client), codec, command, params, false, false); } @Override public RFuture readAsync(RedisClient client, Codec codec, RedisCommand command, Object... params) { - RPromise mainPromise = createPromise(); - async(true, new NodeSource(client), codec, command, params, mainPromise, false, false); - return mainPromise; + return async(true, new NodeSource(client), codec, command, params, false, false); } @Override @@ -188,14 +202,14 @@ public class CommandAsyncService implements CommandAsyncExecutor { @Override public RFuture> readAllAsync(Collection results, Codec codec, RedisCommand command, Object... params) { - RPromise> mainPromise = createPromise(); + CompletableFuture> mainPromise = createPromise(); Collection nodes = connectionManager.getEntrySet(); AtomicInteger counter = new AtomicInteger(nodes.size()); BiConsumer listener = new BiConsumer() { @Override public void accept(Object result, Throwable u) { if (u != null && !(u instanceof RedisRedirectException)) { - mainPromise.tryFailure(u); + mainPromise.completeExceptionally(u); return; } @@ -211,57 +225,54 @@ public class CommandAsyncService implements CommandAsyncExecutor { if (counter.decrementAndGet() == 0 && !mainPromise.isDone()) { - mainPromise.trySuccess(results); + mainPromise.complete(results); } } }; for (MasterSlaveEntry entry : nodes) { - RPromise promise = new RedissonPromise(); - promise.onComplete(listener); - async(true, new NodeSource(entry), codec, command, params, promise, true, false); + RFuture f = async(true, new NodeSource(entry), codec, command, params, true, false); + f.whenComplete(listener); } - return mainPromise; + return new CompletableFutureWrapper<>(mainPromise); } @Override public RFuture readRandomAsync(Codec codec, RedisCommand command, Object... params) { - RPromise mainPromise = createPromise(); + CompletableFuture mainPromise = createPromise(); List nodes = new ArrayList(connectionManager.getEntrySet()); Collections.shuffle(nodes); retryReadRandomAsync(codec, command, mainPromise, nodes, params); - return mainPromise; + return new CompletableFutureWrapper<>(mainPromise); } @Override public RFuture readRandomAsync(MasterSlaveEntry entry, Codec codec, RedisCommand command, Object... params) { - RPromise mainPromise = createPromise(); + CompletableFuture mainPromise = createPromise(); retryReadRandomAsync(codec, command, mainPromise, Collections.singletonList(entry), params); - return mainPromise; + return new CompletableFutureWrapper<>(mainPromise); } - private void retryReadRandomAsync(Codec codec, RedisCommand command, RPromise mainPromise, + private void retryReadRandomAsync(Codec codec, RedisCommand command, CompletableFuture mainPromise, List nodes, Object... params) { - RPromise attemptPromise = new RedissonPromise(); - attemptPromise.onComplete((res, e) -> { + MasterSlaveEntry entry = nodes.remove(0); + RFuture attemptPromise = async(true, new NodeSource(entry), codec, command, params, false, false); + attemptPromise.whenComplete((res, e) -> { if (e == null) { if (res == null) { if (nodes.isEmpty()) { - mainPromise.trySuccess(null); + mainPromise.complete(null); } else { retryReadRandomAsync(codec, command, mainPromise, nodes, params); } } else { - mainPromise.trySuccess(res); + mainPromise.complete(res); } } else { - mainPromise.tryFailure(e); + mainPromise.completeExceptionally(e); } }); - - MasterSlaveEntry entry = nodes.remove(0); - async(true, new NodeSource(entry), codec, command, params, attemptPromise, false, false); } @Override @@ -314,9 +325,8 @@ public class CommandAsyncService implements CommandAsyncExecutor { }; for (MasterSlaveEntry entry : nodes) { - RPromise promise = new RedissonPromise(); - promise.onComplete(listener); - async(readOnlyMode, new NodeSource(entry), codec, command, params, promise, true, false); + RFuture promise = async(readOnlyMode, new NodeSource(entry), codec, command, params, true, false); + promise.whenComplete(listener); } return mainPromise; } @@ -340,24 +350,18 @@ public class CommandAsyncService implements CommandAsyncExecutor { @Override public RFuture readAsync(String key, Codec codec, RedisCommand command, Object... params) { - RPromise mainPromise = createPromise(); NodeSource source = getNodeSource(key); - async(true, source, codec, command, params, mainPromise, false, false); - return mainPromise; + return async(true, source, codec, command, params, false, false); } @Override public RFuture readAsync(byte[] key, Codec codec, RedisCommand command, Object... params) { - RPromise mainPromise = createPromise(); NodeSource source = getNodeSource(key); - async(true, source, codec, command, params, mainPromise, false, false); - return mainPromise; + return async(true, source, codec, command, params, false, false); } public RFuture readAsync(MasterSlaveEntry entry, Codec codec, RedisCommand command, Object... params) { - RPromise mainPromise = createPromise(); - async(true, new NodeSource(entry), codec, command, params, mainPromise, false, false); - return mainPromise; + return async(true, new NodeSource(entry), codec, command, params, false, false); } @Override @@ -368,9 +372,7 @@ public class CommandAsyncService implements CommandAsyncExecutor { @Override public RFuture writeAsync(MasterSlaveEntry entry, Codec codec, RedisCommand command, Object... params) { - RPromise mainPromise = createPromise(); - async(false, new NodeSource(entry), codec, command, params, mainPromise, false, false); - return mainPromise; + return async(false, new NodeSource(entry), codec, command, params, false, false); } @Override @@ -442,9 +444,8 @@ public class CommandAsyncService implements CommandAsyncExecutor { args.addAll(keys); args.addAll(Arrays.asList(params)); for (MasterSlaveEntry entry : entries) { - RPromise promise = new RedissonPromise(); - promise.onComplete(listener); - async(readOnlyMode, new NodeSource(entry), connectionManager.getCodec(), command, args.toArray(), promise, true, false); + RFuture promise = async(readOnlyMode, new NodeSource(entry), connectionManager.getCodec(), command, args.toArray(), true, false); + promise.whenComplete(listener); } return mainPromise; } @@ -498,11 +499,11 @@ public class CommandAsyncService implements CommandAsyncExecutor { private RFuture evalAsync(NodeSource nodeSource, boolean readOnlyMode, Codec codec, RedisCommand evalCommandType, String script, List keys, boolean noRetry, Object... params) { if (isEvalCacheActive() && evalCommandType.getName().equals("EVAL")) { - RPromise mainPromise = new RedissonPromise(); + CompletableFuture mainPromise = new CompletableFuture<>(); Object[] pps = copy(params); - RPromise promise = new RedissonPromise(); + CompletableFuture promise = new CompletableFuture<>(); String sha1 = calcSHA(script); RedisCommand cmd = new RedisCommand(evalCommandType, "EVALSHA"); List args = new ArrayList(2 + keys.size() + params.length); @@ -516,14 +517,14 @@ public class CommandAsyncService implements CommandAsyncExecutor { connectionManager, objectBuilder, referenceType, noRetry); executor.execute(); - promise.onComplete((res, e) -> { + promise.whenComplete((res, e) -> { if (e != null) { if (e.getMessage().startsWith("NOSCRIPT")) { RFuture loadFuture = loadScript(executor.getRedisClient(), script); loadFuture.onComplete((r, ex) -> { if (ex != null) { free(pps); - mainPromise.tryFailure(ex); + mainPromise.completeExceptionally(ex); return; } @@ -539,28 +540,33 @@ public class CommandAsyncService implements CommandAsyncExecutor { ns = new NodeSource(nodeSource, executor.getRedisClient()); } - async(readOnlyMode, ns, codec, command, newargs.toArray(), mainPromise, false, noRetry); + RFuture future = async(readOnlyMode, ns, codec, command, newargs.toArray(), false, noRetry); + future.whenComplete((re, exс) -> { + if (exс != null) { + mainPromise.completeExceptionally(exс); + } else { + mainPromise.complete(re); + } + }); }); } else { free(pps); - mainPromise.tryFailure(e); + mainPromise.completeExceptionally(e); } return; } free(pps); - mainPromise.trySuccess(res); + mainPromise.complete(res); }); - return mainPromise; + return new CompletableFutureWrapper<>(mainPromise); } - RPromise mainPromise = createPromise(); List args = new ArrayList(2 + keys.size() + params.length); args.add(script); args.add(keys.size()); args.addAll(keys); args.addAll(Arrays.asList(params)); - async(readOnlyMode, nodeSource, codec, evalCommandType, args.toArray(), mainPromise, false, noRetry); - return mainPromise; + return async(readOnlyMode, nodeSource, codec, evalCommandType, args.toArray(), false, noRetry); } @Override @@ -570,25 +576,22 @@ public class CommandAsyncService implements CommandAsyncExecutor { @Override public RFuture writeAsync(String key, Codec codec, RedisCommand command, Object... params) { - RPromise mainPromise = createPromise(); NodeSource source = getNodeSource(key); - async(false, source, codec, command, params, mainPromise, false, false); - return mainPromise; + return async(false, source, codec, command, params, false, false); } public RFuture writeAsync(byte[] key, Codec codec, RedisCommand command, Object... params) { - RPromise mainPromise = createPromise(); NodeSource source = getNodeSource(key); - async(false, source, codec, command, params, mainPromise, false, false); - return mainPromise; + return async(false, source, codec, command, params, false, false); } - public void async(boolean readOnlyMode, NodeSource source, Codec codec, - RedisCommand command, Object[] params, RPromise mainPromise, - boolean ignoreRedirect, boolean noRetry) { + public RFuture async(boolean readOnlyMode, NodeSource source, Codec codec, + RedisCommand command, Object[] params, boolean ignoreRedirect, boolean noRetry) { + CompletableFuture mainPromise = createPromise(); RedisExecutor executor = new RedisExecutor<>(readOnlyMode, source, codec, command, params, mainPromise, ignoreRedirect, connectionManager, objectBuilder, referenceType, noRetry); executor.execute(); + return new CompletableFutureWrapper<>(mainPromise); } private void free(Object[] params) { diff --git a/redisson/src/main/java/org/redisson/command/CommandBatchService.java b/redisson/src/main/java/org/redisson/command/CommandBatchService.java index 1e383b61b..23b342164 100644 --- a/redisson/src/main/java/org/redisson/command/CommandBatchService.java +++ b/redisson/src/main/java/org/redisson/command/CommandBatchService.java @@ -34,6 +34,7 @@ import org.redisson.connection.MasterSlaveEntry; import org.redisson.connection.NodeSource; import org.redisson.liveobject.core.RedissonObjectBuilder; import org.redisson.misc.AsyncCountDownLatch; +import org.redisson.misc.CompletableFutureWrapper; import org.redisson.misc.RPromise; import org.redisson.misc.RedissonPromise; @@ -53,14 +54,14 @@ public class CommandBatchService extends CommandAsyncService { public static class ConnectionEntry { boolean firstCommand = true; - RFuture connectionFuture; + CompletableFuture connectionFuture; Runnable cancelCallback; - public RFuture getConnectionFuture() { + public CompletableFuture getConnectionFuture() { return connectionFuture; } - public void setConnectionFuture(RFuture connectionFuture) { + public void setConnectionFuture(CompletableFuture connectionFuture) { this.connectionFuture = connectionFuture; } @@ -151,8 +152,9 @@ public class CommandBatchService extends CommandAsyncService { } @Override - public void async(boolean readOnlyMode, NodeSource nodeSource, - Codec codec, RedisCommand command, Object[] params, RPromise mainPromise, boolean ignoreRedirect, boolean noRetry) { + public RFuture async(boolean readOnlyMode, NodeSource nodeSource, + Codec codec, RedisCommand command, Object[] params, boolean ignoreRedirect, boolean noRetry) { + CompletableFuture mainPromise = createPromise(); if (isRedisBasedQueue()) { boolean isReadOnly = options.getExecutionMode() == ExecutionMode.REDIS_READ_ATOMIC; RedisExecutor executor = new RedisQueuedBatchExecutor<>(isReadOnly, nodeSource, codec, command, params, mainPromise, @@ -163,16 +165,16 @@ public class CommandBatchService extends CommandAsyncService { false, connectionManager, objectBuilder, commands, options, index, executed, referenceType, noRetry); executor.execute(); } - + return new CompletableFutureWrapper<>(mainPromise); } @Override - public RPromise createPromise() { + public CompletableFuture createPromise() { if (isRedisBasedQueue()) { - return new BatchPromise<>(executed); + return new BatchPromise<>(); } - return new RedissonPromise<>(); + return new CompletableFuture<>(); } public void discard() { @@ -260,10 +262,10 @@ public class CommandBatchService extends CommandAsyncService { } RPromise> promise = new RedissonPromise<>(); - RPromise voidPromise = new RedissonPromise(); + CompletableFuture voidPromise = new CompletableFuture<>(); if (this.options.isSkipResult() && this.options.getSyncSlaves() == 0) { - voidPromise.onComplete((res, ex) -> { + voidPromise.whenComplete((res, ex) -> { executed.set(true); if (ex != null) { @@ -283,7 +285,7 @@ public class CommandBatchService extends CommandAsyncService { promise.trySuccess(new BatchResult<>(Collections.emptyList(), 0)); }); } else { - voidPromise.onComplete((res, ex) -> { + voidPromise.whenComplete((res, ex) -> { executed.set(true); if (ex != null) { for (Entry e : commands.values()) { @@ -306,7 +308,7 @@ public class CommandBatchService extends CommandAsyncService { int syncedSlaves = 0; for (BatchCommandData commandEntry : entries) { if (isWaitCommand(commandEntry)) { - syncedSlaves = (Integer) commandEntry.getPromise().getNow(); + syncedSlaves = (Integer) commandEntry.getPromise().getNow(null); } else if (!commandEntry.getCommand().getName().equals(RedisCommands.MULTI.getName()) && !commandEntry.getCommand().getName().equals(RedisCommands.EXEC.getName()) && !this.options.isSkipResult()) { @@ -315,7 +317,7 @@ public class CommandBatchService extends CommandAsyncService { continue; } - Object entryResult = commandEntry.getPromise().getNow(); + Object entryResult = commandEntry.getPromise().getNow(null); try { if (objectBuilder != null) { entryResult = objectBuilder.tryHandleReference(entryResult, referenceType); @@ -356,6 +358,17 @@ public class CommandBatchService extends CommandAsyncService { return promise; } + protected Throwable cause(CompletableFuture future) { + try { + future.getNow(null); + return null; + } catch (CompletionException ex2) { + return ex2.getCause(); + } catch (CancellationException ex1) { + return ex1; + } + } + private RFuture executeRedisBasedQueue() { int permits = 0; for (Entry entry : commands.values()) { @@ -393,8 +406,9 @@ public class CommandBatchService extends CommandAsyncService { for (Entry entry : commands.values()) { for (BatchCommandData command : entry.getCommands()) { - if (command.getPromise().isDone() && !command.getPromise().isSuccess()) { - resultPromise.tryFailure(command.getPromise().cause()); + if (command.getPromise().isDone() && command.getPromise().isCompletedExceptionally()) { + + resultPromise.tryFailure(cause(command.getPromise())); break; } } @@ -407,10 +421,8 @@ public class CommandBatchService extends CommandAsyncService { Map> result = new ConcurrentHashMap<>(); List> futures = new ArrayList<>(commands.size()); for (Map.Entry entry : commands.entrySet()) { - RPromise> execPromise = new RedissonPromise<>(); - - async(entry.getValue().isReadOnlyMode(), new NodeSource(entry.getKey()), connectionManager.getCodec(), RedisCommands.EXEC, - new Object[] {}, execPromise, false, false); + RFuture> execPromise = async(entry.getValue().isReadOnlyMode(), new NodeSource(entry.getKey()), + connectionManager.getCodec(), RedisCommands.EXEC, new Object[] {}, false, false); CompletionStage f = execPromise.thenCompose(r -> { BatchCommandData lastCommand = (BatchCommandData) entry.getValue().getCommands().peekLast(); @@ -441,12 +453,12 @@ public class CommandBatchService extends CommandAsyncService { break; } - RPromise promise = (RPromise) data.getPromise(); + CompletableFuture promise = (CompletableFuture) data.getPromise(); if (resultIter.hasNext()) { - promise.trySuccess(resultIter.next()); + promise.complete(resultIter.next()); } else { // fix for https://github.com/redisson/redisson/issues/2212 - promise.trySuccess(null); + promise.complete(null); } } } @@ -460,17 +472,17 @@ public class CommandBatchService extends CommandAsyncService { int syncedSlaves = 0; for (BatchCommandData commandEntry : entries) { if (isWaitCommand(commandEntry)) { - syncedSlaves += (Integer) commandEntry.getPromise().getNow(); + syncedSlaves += (Integer) commandEntry.getPromise().getNow(null); } else if (!commandEntry.getCommand().getName().equals(RedisCommands.MULTI.getName()) && !commandEntry.getCommand().getName().equals(RedisCommands.EXEC.getName())) { - Object entryResult = commandEntry.getPromise().getNow(); + Object entryResult = commandEntry.getPromise().getNow(null); if (objectBuilder != null) { entryResult = objectBuilder.tryHandleReference(entryResult, referenceType); } responses.add(entryResult); } } - BatchResult r = new BatchResult(responses, syncedSlaves); + BatchResult r = new BatchResult<>(responses, syncedSlaves); resultPromise.trySuccess((R) r); } catch (Exception e) { resultPromise.tryFailure(e); @@ -490,13 +502,13 @@ public class CommandBatchService extends CommandAsyncService { return c.getCommand().getName().equals(RedisCommands.WAIT.getName()); } - protected void handle(RPromise mainPromise, AtomicInteger slots, RFuture future) { + protected void handle(CompletableFuture mainPromise, AtomicInteger slots, RFuture future) { if (future.isSuccess()) { if (slots.decrementAndGet() == 0) { - mainPromise.trySuccess(null); + mainPromise.complete(null); } } else { - mainPromise.tryFailure(future.cause()); + mainPromise.completeExceptionally(future.cause()); } } diff --git a/redisson/src/main/java/org/redisson/command/RedisBatchExecutor.java b/redisson/src/main/java/org/redisson/command/RedisBatchExecutor.java index 39bbbb660..3e3493e80 100644 --- a/redisson/src/main/java/org/redisson/command/RedisBatchExecutor.java +++ b/redisson/src/main/java/org/redisson/command/RedisBatchExecutor.java @@ -15,10 +15,6 @@ */ package org.redisson.command; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; - import org.redisson.api.BatchOptions; import org.redisson.client.codec.Codec; import org.redisson.client.protocol.RedisCommand; @@ -27,7 +23,11 @@ import org.redisson.connection.ConnectionManager; import org.redisson.connection.MasterSlaveEntry; import org.redisson.connection.NodeSource; import org.redisson.liveobject.core.RedissonObjectBuilder; -import org.redisson.misc.RPromise; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; /** * @@ -40,7 +40,7 @@ public class RedisBatchExecutor extends BaseRedisBatchExecutor { @SuppressWarnings("ParameterNumber") public RedisBatchExecutor(boolean readOnlyMode, NodeSource source, Codec codec, RedisCommand command, - Object[] params, RPromise mainPromise, boolean ignoreRedirect, ConnectionManager connectionManager, + Object[] params, CompletableFuture mainPromise, boolean ignoreRedirect, ConnectionManager connectionManager, RedissonObjectBuilder objectBuilder, ConcurrentMap commands, BatchOptions options, AtomicInteger index, AtomicBoolean executed, RedissonObjectBuilder.ReferenceType referenceType, boolean noRetry) { diff --git a/redisson/src/main/java/org/redisson/command/RedisCommonBatchExecutor.java b/redisson/src/main/java/org/redisson/command/RedisCommonBatchExecutor.java index d8f8c16cd..0d9f8ed37 100644 --- a/redisson/src/main/java/org/redisson/command/RedisCommonBatchExecutor.java +++ b/redisson/src/main/java/org/redisson/command/RedisCommonBatchExecutor.java @@ -20,7 +20,6 @@ import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelPromise; import org.redisson.api.BatchOptions; import org.redisson.api.BatchOptions.ExecutionMode; -import org.redisson.api.RFuture; import org.redisson.client.RedisConnection; import org.redisson.client.codec.StringCodec; import org.redisson.client.protocol.CommandData; @@ -31,13 +30,12 @@ import org.redisson.connection.ConnectionManager; import org.redisson.connection.NodeSource; import org.redisson.connection.NodeSource.Redirect; import org.redisson.liveobject.core.RedissonObjectBuilder; -import org.redisson.misc.RPromise; -import org.redisson.misc.RedissonPromise; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicInteger; /** @@ -53,7 +51,7 @@ public class RedisCommonBatchExecutor extends RedisExecutor { private final AtomicInteger slots; private final BatchOptions options; - public RedisCommonBatchExecutor(NodeSource source, RPromise mainPromise, + public RedisCommonBatchExecutor(NodeSource source, CompletableFuture mainPromise, ConnectionManager connectionManager, BatchOptions options, Entry entry, AtomicInteger slots, RedissonObjectBuilder.ReferenceType referenceType, boolean noRetry) { super(entry.isReadOnlyMode(), source, null, null, null, @@ -93,18 +91,18 @@ public class RedisCommonBatchExecutor extends RedisExecutor { } @Override - protected void sendCommand(RPromise attemptPromise, RedisConnection connection) { + protected void sendCommand(CompletableFuture attemptPromise, RedisConnection connection) { boolean isAtomic = options.getExecutionMode() != ExecutionMode.IN_MEMORY; boolean isQueued = options.getExecutionMode() == ExecutionMode.REDIS_READ_ATOMIC || options.getExecutionMode() == ExecutionMode.REDIS_WRITE_ATOMIC; List> list = new ArrayList<>(entry.getCommands().size()); if (source.getRedirect() == Redirect.ASK) { - RPromise promise = new RedissonPromise(); + CompletableFuture promise = new CompletableFuture(); list.add(new CommandData<>(promise, StringCodec.INSTANCE, RedisCommands.ASKING, new Object[] {})); } for (CommandData c : entry.getCommands()) { - if ((c.getPromise().isCancelled() || c.getPromise().isSuccess()) + if ((c.getPromise().isCancelled() || (c.getPromise().isDone() && !c.getPromise().isCompletedExceptionally())) && !isWaitCommand(c) && !isAtomic) { // skip command @@ -115,7 +113,7 @@ public class RedisCommonBatchExecutor extends RedisExecutor { if (list.isEmpty()) { writeFuture = connection.getChannel().newPromise(); - attemptPromise.trySuccess(null); + attemptPromise.complete(null); timeout.cancel(); return; } @@ -123,7 +121,7 @@ public class RedisCommonBatchExecutor extends RedisExecutor { sendCommand(connection, attemptPromise, list); } - private void sendCommand(RedisConnection connection, RPromise attemptPromise, List> list) { + private void sendCommand(RedisConnection connection, CompletableFuture attemptPromise, List> list) { boolean isAtomic = options.getExecutionMode() != ExecutionMode.IN_MEMORY; boolean isQueued = options.getExecutionMode() == ExecutionMode.REDIS_READ_ATOMIC || options.getExecutionMode() == ExecutionMode.REDIS_WRITE_ATOMIC; @@ -131,7 +129,7 @@ public class RedisCommonBatchExecutor extends RedisExecutor { CommandData lastCommand = connection.getLastCommand(); if (lastCommand != null && options.isSkipResult()) { writeFuture = connection.getChannel().newPromise(); - lastCommand.getPromise().onComplete((r, e) -> { + lastCommand.getPromise().whenComplete((r, e) -> { CommandData currentLastCommand = connection.getLastCommand(); if (lastCommand != currentLastCommand && currentLastCommand != null) { sendCommand(connection, attemptPromise, list); @@ -158,13 +156,13 @@ public class RedisCommonBatchExecutor extends RedisExecutor { } @Override - protected void handleResult(RPromise attemptPromise, RFuture connectionFuture) throws ReflectiveOperationException { - if (attemptPromise.isSuccess()) { + protected void handleResult(CompletableFuture attemptPromise, CompletableFuture connectionFuture) throws ReflectiveOperationException { + if (attemptPromise.isDone() && !attemptPromise.isCompletedExceptionally()) { if (slots.decrementAndGet() == 0) { - mainPromise.trySuccess(null); + mainPromise.complete(null); } } else { - mainPromise.tryFailure(attemptPromise.cause()); + mainPromise.completeExceptionally(cause(attemptPromise)); } } diff --git a/redisson/src/main/java/org/redisson/command/RedisExecutor.java b/redisson/src/main/java/org/redisson/command/RedisExecutor.java index 329e007d2..3103f8729 100644 --- a/redisson/src/main/java/org/redisson/command/RedisExecutor.java +++ b/redisson/src/main/java/org/redisson/command/RedisExecutor.java @@ -24,7 +24,6 @@ import io.netty.util.TimerTask; import io.netty.util.concurrent.FutureListener; import org.redisson.RedissonShutdownException; import org.redisson.ScanResult; -import org.redisson.api.RFuture; import org.redisson.cache.LRUCacheMap; import org.redisson.client.*; import org.redisson.client.codec.BaseCodec; @@ -38,16 +37,16 @@ import org.redisson.connection.NodeSource; import org.redisson.connection.NodeSource.Redirect; import org.redisson.liveobject.core.RedissonObjectBuilder; import org.redisson.misc.LogHelper; -import org.redisson.misc.RPromise; import org.redisson.misc.RedisURI; -import org.redisson.misc.RedissonPromise; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.concurrent.CancellationException; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; import java.util.concurrent.TimeUnit; import java.util.function.BiConsumer; @@ -66,14 +65,14 @@ public class RedisExecutor { final boolean readOnlyMode; final RedisCommand command; final Object[] params; - final RPromise mainPromise; + final CompletableFuture mainPromise; final boolean ignoreRedirect; final RedissonObjectBuilder objectBuilder; final ConnectionManager connectionManager; final RedissonObjectBuilder.ReferenceType referenceType; final boolean noRetry; - RFuture connectionFuture; + CompletableFuture connectionFuture; NodeSource source; Codec codec; volatile int attempt; @@ -87,7 +86,7 @@ public class RedisExecutor { long responseTimeout; public RedisExecutor(boolean readOnlyMode, NodeSource source, Codec codec, RedisCommand command, - Object[] params, RPromise mainPromise, boolean ignoreRedirect, + Object[] params, CompletableFuture mainPromise, boolean ignoreRedirect, ConnectionManager connectionManager, RedissonObjectBuilder objectBuilder, RedissonObjectBuilder.ReferenceType referenceType, boolean noRetry) { super(); @@ -116,15 +115,15 @@ public class RedisExecutor { if (!connectionManager.getShutdownLatch().acquire()) { free(); - mainPromise.tryFailure(new RedissonShutdownException("Redisson is shutdown")); + mainPromise.completeExceptionally(new RedissonShutdownException("Redisson is shutdown")); return; } codec = getCodec(codec); - RFuture connectionFuture = getConnection(); + CompletableFuture connectionFuture = getConnection().toCompletableFuture(); - RPromise attemptPromise = new RedissonPromise<>(); + CompletableFuture attemptPromise = new CompletableFuture<>(); mainPromiseListener = (r, e) -> { if (mainPromise.isCancelled() && connectionFuture.cancel(false)) { log.debug("Connection obtaining canceled for {}", command); @@ -136,7 +135,7 @@ public class RedisExecutor { }; if (attempt == 0) { - mainPromise.onComplete((r, e) -> { + mainPromise.whenComplete((r, e) -> { if (this.mainPromiseListener != null) { this.mainPromiseListener.accept(r, e); } @@ -145,13 +144,13 @@ public class RedisExecutor { scheduleRetryTimeout(connectionFuture, attemptPromise); - connectionFuture.onComplete((connection, e) -> { + connectionFuture.whenComplete((connection, e) -> { if (connectionFuture.isCancelled()) { connectionManager.getShutdownLatch().release(); return; } - if (!connectionFuture.isSuccess()) { + if (connectionFuture.isDone() && connectionFuture.isCompletedExceptionally()) { connectionManager.getShutdownLatch().release(); exception = convertException(connectionFuture); return; @@ -167,14 +166,14 @@ public class RedisExecutor { }); }); - attemptPromise.onComplete((r, e) -> { + attemptPromise.whenComplete((r, e) -> { releaseConnection(attemptPromise, connectionFuture); checkAttemptPromise(attemptPromise, connectionFuture); }); } - private void scheduleRetryTimeout(RFuture connectionFuture, RPromise attemptPromise) { + private void scheduleRetryTimeout(CompletableFuture connectionFuture, CompletableFuture attemptPromise) { TimerTask retryTimerTask = new TimerTask() { @Override @@ -190,7 +189,7 @@ public class RedisExecutor { + ", command: " + LogHelper.toString(command, params) + " after " + attempt + " retry attempts"); } else { - if (connectionFuture.isSuccess()) { + if (connectionFuture.isDone() && !connectionFuture.isCompletedExceptionally()) { if (writeFuture == null || !writeFuture.isDone()) { if (attempt == attempts) { if (writeFuture != null && writeFuture.cancel(false)) { @@ -206,11 +205,11 @@ public class RedisExecutor { exception = new RedisTimeoutException("Command still hasn't been written into connection! " + "Try to increase nettyThreads setting. Payload size in bytes: " + totalSize - + ". Node source: " + source + ", connection: " + connectionFuture.getNow() + + ". Node source: " + source + ", connection: " + getNow(connectionFuture) + ", command: " + LogHelper.toString(command, params) + " after " + attempt + " retry attempts"); } - attemptPromise.tryFailure(exception); + attemptPromise.completeExceptionally(exception); } return; } @@ -236,7 +235,7 @@ public class RedisExecutor { if (attempt == attempts) { // filled out in connectionFuture or writeFuture handler if (exception != null) { - attemptPromise.tryFailure(exception); + attemptPromise.completeExceptionally(exception); } return; } @@ -270,7 +269,7 @@ public class RedisExecutor { } } - private void checkWriteFuture(ChannelFuture future, RPromise attemptPromise, RedisConnection connection) { + private void checkWriteFuture(ChannelFuture future, CompletableFuture attemptPromise, RedisConnection connection) { if (future.isCancelled() || attemptPromise.isDone()) { return; } @@ -281,7 +280,7 @@ public class RedisExecutor { ", command: " + LogHelper.toString(command, params) + " after " + attempt + " retry attempts", future.cause()); if (attempt == attempts) { - attemptPromise.tryFailure(exception); + attemptPromise.completeExceptionally(exception); } return; } @@ -291,7 +290,7 @@ public class RedisExecutor { scheduleResponseTimeout(attemptPromise, connection); } - private void scheduleResponseTimeout(RPromise attemptPromise, RedisConnection connection) { + private void scheduleResponseTimeout(CompletableFuture attemptPromise, RedisConnection connection) { long timeoutTime = responseTimeout; if (command != null && command.isBlockingCommand()) { Long popTimeout = null; @@ -335,7 +334,7 @@ public class RedisExecutor { return; } - attemptPromise.tryFailure( + attemptPromise.completeExceptionally( new RedisResponseTimeoutException("Redis server response timeout (" + timeoutAmount + " ms) occured" + " after " + attempt + " retry attempts. Increase nettyThreads and/or timeout settings. Try to define pingConnectionInterval setting. Command: " + LogHelper.toString(command, params) + ", channel: " + connection.getChannel())); @@ -350,16 +349,16 @@ public class RedisExecutor { && (command == null || (!command.isBlockingCommand() && !RedisCommands.NO_RETRY.contains(command.getName()))); } - private void handleBlockingOperations(RPromise attemptPromise, RedisConnection connection, Long popTimeout) { + private void handleBlockingOperations(CompletableFuture attemptPromise, RedisConnection connection, Long popTimeout) { FutureListener listener = f -> { - mainPromise.tryFailure(new RedissonShutdownException("Redisson is shutdown")); + mainPromise.completeExceptionally(new RedissonShutdownException("Redisson is shutdown")); }; Timeout scheduledFuture; if (popTimeout != 0) { // handling cases when connection has been lost scheduledFuture = connectionManager.newTimeout(timeout -> { - if (attemptPromise.trySuccess(null)) { + if (attemptPromise.complete(null)) { connection.forceFastReconnectAsync(); } }, popTimeout + 1, TimeUnit.SECONDS); @@ -367,7 +366,7 @@ public class RedisExecutor { scheduledFuture = null; } - mainPromise.onComplete((res, e) -> { + mainPromise.whenComplete((res, e) -> { if (scheduledFuture != null) { scheduledFuture.cancel(); } @@ -378,17 +377,17 @@ public class RedisExecutor { // handling cancel operation for blocking commands if ((mainPromise.isCancelled() - || mainPromise.cause() instanceof InterruptedException) + || e instanceof InterruptedException) && !attemptPromise.isDone()) { log.debug("Canceled blocking operation {} used {}", command, connection); - connection.forceFastReconnectAsync().onComplete((r, ex) -> { + connection.forceFastReconnectAsync().whenComplete((r, ex) -> { attemptPromise.cancel(true); }); return; } if (e instanceof RedissonShutdownException) { - attemptPromise.tryFailure(e); + attemptPromise.completeExceptionally(e); } }); @@ -399,7 +398,18 @@ public class RedisExecutor { } } - protected void checkAttemptPromise(RPromise attemptFuture, RFuture connectionFuture) { + protected Throwable cause(CompletableFuture future) { + try { + future.getNow(null); + return null; + } catch (CompletionException ex2) { + return ex2.getCause(); + } catch (CancellationException ex1) { + return ex1; + } + } + + protected void checkAttemptPromise(CompletableFuture attemptFuture, CompletableFuture connectionFuture) { timeout.cancel(); if (attemptFuture.isCancelled()) { return; @@ -408,10 +418,11 @@ public class RedisExecutor { try { mainPromiseListener = null; - if (attemptFuture.cause() instanceof RedisMovedException && !ignoreRedirect) { - RedisMovedException ex = (RedisMovedException) attemptFuture.cause(); + Throwable cause = cause(attemptFuture); + if (cause instanceof RedisMovedException && !ignoreRedirect) { + RedisMovedException ex = (RedisMovedException) cause; if (source.getRedirect() == Redirect.MOVED) { - mainPromise.tryFailure(new RedisException("MOVED redirection loop detected. Node " + source.getAddr() + " has further redirect to " + ex.getUrl())); + mainPromise.completeExceptionally(new RedisException("MOVED redirection loop detected. Node " + source.getAddr() + " has further redirect to " + ex.getUrl())); return; } @@ -429,8 +440,8 @@ public class RedisExecutor { return; } - if (attemptFuture.cause() instanceof RedisAskException && !ignoreRedirect) { - RedisAskException ex = (RedisAskException) attemptFuture.cause(); + if (cause instanceof RedisAskException && !ignoreRedirect) { + RedisAskException ex = (RedisAskException) cause; onException(); @@ -446,10 +457,10 @@ public class RedisExecutor { return; } - if (attemptFuture.cause() instanceof RedisLoadingException - || attemptFuture.cause() instanceof RedisTryAgainException - || attemptFuture.cause() instanceof RedisClusterDownException - || attemptFuture.cause() instanceof RedisBusyException) { + if (cause instanceof RedisLoadingException + || cause instanceof RedisTryAgainException + || cause instanceof RedisClusterDownException + || cause instanceof RedisBusyException) { if (attempt < attempts) { onException(); connectionManager.newTimeout(timeout -> { @@ -469,49 +480,55 @@ public class RedisExecutor { } } - protected void handleResult(RPromise attemptPromise, RFuture connectionFuture) throws ReflectiveOperationException { - if (attemptPromise.isSuccess()) { - R res = attemptPromise.getNow(); - if (res instanceof ScanResult) { - ((ScanResult) res).setRedisClient(connectionFuture.getNow().getRedisClient()); - } + protected void handleResult(CompletableFuture attemptPromise, CompletableFuture connectionFuture) throws ReflectiveOperationException { + R res; + try { + res = attemptPromise.getNow(null); + } catch (CompletionException e) { + handleError(connectionFuture, e.getCause()); + return; + } catch (CancellationException e) { + handleError(connectionFuture, e); + return; + } - handleSuccess(mainPromise, connectionFuture, res); - } else { - handleError(connectionFuture, attemptPromise.cause()); + if (res instanceof ScanResult) { + ((ScanResult) res).setRedisClient(getNow(connectionFuture).getRedisClient()); } + + handleSuccess(mainPromise, connectionFuture, res); } protected void onException() { } - protected void handleError(RFuture connectionFuture, Throwable cause) { - mainPromise.tryFailure(cause); + protected void handleError(CompletableFuture connectionFuture, Throwable cause) { + mainPromise.completeExceptionally(cause); } - protected void handleSuccess(RPromise promise, RFuture connectionFuture, R res) throws ReflectiveOperationException { + protected void handleSuccess(CompletableFuture promise, CompletableFuture connectionFuture, R res) throws ReflectiveOperationException { if (objectBuilder != null) { handleReference(promise, res); } else { - promise.trySuccess(res); + promise.complete(res); } } - private void handleReference(RPromise promise, R res) throws ReflectiveOperationException { + private void handleReference(CompletableFuture promise, R res) throws ReflectiveOperationException { if (objectBuilder != null) { - promise.trySuccess((R) objectBuilder.tryHandleReference(res, referenceType)); + promise.complete((R) objectBuilder.tryHandleReference(res, referenceType)); } else { - promise.trySuccess(res); + promise.complete(res); } } - protected void sendCommand(RPromise attemptPromise, RedisConnection connection) { + protected void sendCommand(CompletableFuture attemptPromise, RedisConnection connection) { if (source.getRedirect() == Redirect.ASK) { List> list = new ArrayList<>(2); - RPromise promise = new RedissonPromise<>(); + CompletableFuture promise = new CompletableFuture<>(); list.add(new CommandData<>(promise, codec, RedisCommands.ASKING, new Object[]{})); list.add(new CommandData<>(attemptPromise, codec, command, params)); - RPromise main = new RedissonPromise<>(); + CompletableFuture main = new CompletableFuture<>(); writeFuture = connection.send(new CommandsData(main, list, false, false)); } else { if (log.isDebugEnabled()) { @@ -530,12 +547,12 @@ public class RedisExecutor { } } - protected void releaseConnection(RPromise attemptPromise, RFuture connectionFuture) { - if (!connectionFuture.isSuccess()) { + protected void releaseConnection(CompletableFuture attemptPromise, CompletableFuture connectionFuture) { + if (connectionFuture.isDone() && connectionFuture.isCompletedExceptionally()) { return; } - RedisConnection connection = connectionFuture.getNow(); + RedisConnection connection = getNow(connectionFuture); connectionManager.getShutdownLatch().release(); if (connectionManager.getConfig().getMasterConnectionPoolSize() < 10) { if (source.getRedirect() == Redirect.ASK || getClass() != RedisExecutor.class) { @@ -565,10 +582,10 @@ public class RedisExecutor { } public RedisClient getRedisClient() { - return connectionFuture.getNow().getRedisClient(); + return getNow(connectionFuture).getRedisClient(); } - protected RFuture getConnection() { + protected CompletableFuture getConnection() { if (readOnlyMode) { connectionFuture = connectionManager.connectionReadOp(source, command); } else { @@ -615,11 +632,20 @@ public class RedisExecutor { return codecToUse; } - protected RedisException convertException(RFuture future) { - if (future.cause() instanceof RedisException) { - return (RedisException) future.cause(); + protected T getNow(CompletableFuture future) { + try { + return future.getNow(null); + } catch (Exception e) { + return null; + } + } + + protected RedisException convertException(CompletableFuture future) { + Throwable cause = cause(future); + if (cause instanceof RedisException) { + return (RedisException) cause; } - return new RedisException("Unexpected exception while processing command", future.cause()); + return new RedisException("Unexpected exception while processing command", cause); } diff --git a/redisson/src/main/java/org/redisson/command/RedisQueuedBatchExecutor.java b/redisson/src/main/java/org/redisson/command/RedisQueuedBatchExecutor.java index 3ce40d7fd..85ad45069 100644 --- a/redisson/src/main/java/org/redisson/command/RedisQueuedBatchExecutor.java +++ b/redisson/src/main/java/org/redisson/command/RedisQueuedBatchExecutor.java @@ -17,7 +17,6 @@ package org.redisson.command; import org.redisson.api.BatchOptions; import org.redisson.api.BatchOptions.ExecutionMode; -import org.redisson.api.RFuture; import org.redisson.client.RedisConnection; import org.redisson.client.codec.Codec; import org.redisson.client.protocol.*; @@ -30,12 +29,12 @@ import org.redisson.connection.NodeSource.Redirect; import org.redisson.liveobject.core.RedissonObjectBuilder; import org.redisson.misc.AsyncCountDownLatch; import org.redisson.misc.LogHelper; -import org.redisson.misc.RPromise; import org.redisson.misc.RedissonPromise; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CancellationException; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; @@ -54,7 +53,7 @@ public class RedisQueuedBatchExecutor extends BaseRedisBatchExecutor @SuppressWarnings("ParameterNumber") public RedisQueuedBatchExecutor(boolean readOnlyMode, NodeSource source, Codec codec, RedisCommand command, - Object[] params, RPromise mainPromise, boolean ignoreRedirect, ConnectionManager connectionManager, + Object[] params, CompletableFuture mainPromise, boolean ignoreRedirect, ConnectionManager connectionManager, RedissonObjectBuilder objectBuilder, ConcurrentMap commands, ConcurrentMap connections, BatchOptions options, AtomicInteger index, AtomicBoolean executed, AsyncCountDownLatch latch, RedissonObjectBuilder.ReferenceType referenceType, @@ -79,7 +78,7 @@ public class RedisQueuedBatchExecutor extends BaseRedisBatchExecutor @Override - protected void releaseConnection(RPromise attemptPromise, RFuture connectionFuture) { + protected void releaseConnection(CompletableFuture attemptPromise, CompletableFuture connectionFuture) { if (RedisCommands.EXEC.getName().equals(command.getName()) || RedisCommands.DISCARD.getName().equals(command.getName())) { super.releaseConnection(attemptPromise, connectionFuture); @@ -89,7 +88,7 @@ public class RedisQueuedBatchExecutor extends BaseRedisBatchExecutor } @Override - protected void handleSuccess(RPromise promise, RFuture connectionFuture, R res) + protected void handleSuccess(CompletableFuture promise, CompletableFuture connectionFuture, R res) throws ReflectiveOperationException { if (RedisCommands.EXEC.getName().equals(command.getName())) { super.handleSuccess(promise, connectionFuture, res); @@ -102,7 +101,7 @@ public class RedisQueuedBatchExecutor extends BaseRedisBatchExecutor try { BatchPromise batchPromise = (BatchPromise) promise; - RPromise sentPromise = (RPromise) batchPromise.getSentPromise(); + CompletableFuture sentPromise = batchPromise.getSentPromise(); super.handleSuccess(sentPromise, connectionFuture, null); } finally { latch.countDown(); @@ -110,15 +109,15 @@ public class RedisQueuedBatchExecutor extends BaseRedisBatchExecutor } @Override - protected void handleError(RFuture connectionFuture, Throwable cause) { + protected void handleError(CompletableFuture connectionFuture, Throwable cause) { try { if (mainPromise instanceof BatchPromise) { BatchPromise batchPromise = (BatchPromise) mainPromise; - RPromise sentPromise = (RPromise) batchPromise.getSentPromise(); - sentPromise.tryFailure(cause); - mainPromise.tryFailure(cause); + CompletableFuture sentPromise = batchPromise.getSentPromise(); + sentPromise.completeExceptionally(cause); + mainPromise.completeExceptionally(cause); if (executed.compareAndSet(false, true)) { - connectionFuture.getNow().forceFastReconnectAsync().onComplete((res, e) -> { + getNow(connectionFuture).forceFastReconnectAsync().whenComplete((res, e) -> { RedisQueuedBatchExecutor.super.releaseConnection(mainPromise, connectionFuture); }); } @@ -132,7 +131,7 @@ public class RedisQueuedBatchExecutor extends BaseRedisBatchExecutor } @Override - protected void sendCommand(RPromise attemptPromise, RedisConnection connection) { + protected void sendCommand(CompletableFuture attemptPromise, RedisConnection connection) { MasterSlaveEntry msEntry = getEntry(source); ConnectionEntry connectionEntry = connections.get(msEntry); @@ -140,14 +139,14 @@ public class RedisQueuedBatchExecutor extends BaseRedisBatchExecutor if (source.getRedirect() == Redirect.ASK) { List> list = new ArrayList>(2); - RPromise promise = new RedissonPromise(); - list.add(new CommandData(promise, codec, RedisCommands.ASKING, new Object[]{})); + CompletableFuture promise = new CompletableFuture<>(); + list.add(new CommandData<>(promise, codec, RedisCommands.ASKING, new Object[]{})); if (connectionEntry.isFirstCommand()) { - list.add(new CommandData(promise, codec, RedisCommands.MULTI, new Object[]{})); + list.add(new CommandData<>(promise, codec, RedisCommands.MULTI, new Object[]{})); connectionEntry.setFirstCommand(false); } list.add(new CommandData(attemptPromise, codec, command, params)); - RPromise main = new RedissonPromise(); + CompletableFuture main = new CompletableFuture<>(); writeFuture = connection.send(new CommandsData(main, list, true, syncSlaves)); } else { if (log.isDebugEnabled()) { @@ -157,9 +156,9 @@ public class RedisQueuedBatchExecutor extends BaseRedisBatchExecutor if (connectionEntry.isFirstCommand()) { List> list = new ArrayList>(2); - list.add(new CommandData(new RedissonPromise(), codec, RedisCommands.MULTI, new Object[]{})); - list.add(new CommandData(attemptPromise, codec, command, params)); - RPromise main = new RedissonPromise(); + list.add(new CommandData<>(new RedissonPromise(), codec, RedisCommands.MULTI, new Object[]{})); + list.add(new CommandData<>(attemptPromise, codec, command, params)); + CompletableFuture main = new CompletableFuture<>(); writeFuture = connection.send(new CommandsData(main, list, true, syncSlaves)); connectionEntry.setFirstCommand(false); } else { @@ -184,13 +183,13 @@ public class RedisQueuedBatchExecutor extends BaseRedisBatchExecutor entry.getCommands().add(waitCommand); } - RPromise main = new RedissonPromise(); + CompletableFuture main = new CompletableFuture<>(); writeFuture = connection.send(new CommandsData(main, list, new ArrayList(entry.getCommands()), options.isSkipResult(), false, true, syncSlaves)); } else { - RPromise main = new RedissonPromise(); + CompletableFuture main = new CompletableFuture<>(); List> list = new ArrayList<>(); - list.add(new CommandData(attemptPromise, codec, command, params)); + list.add(new CommandData<>(attemptPromise, codec, command, params)); writeFuture = connection.send(new CommandsData(main, list, true, syncSlaves)); } } @@ -198,7 +197,7 @@ public class RedisQueuedBatchExecutor extends BaseRedisBatchExecutor } @Override - protected RFuture getConnection() { + protected CompletableFuture getConnection() { MasterSlaveEntry msEntry = getEntry(source); ConnectionEntry entry = connections.get(msEntry); if (entry == null) { @@ -218,8 +217,8 @@ public class RedisQueuedBatchExecutor extends BaseRedisBatchExecutor if (entry.getConnectionFuture() != null) { return entry.getConnectionFuture(); } - - RFuture connectionFuture; + + CompletableFuture connectionFuture; if (this.options.getExecutionMode() == ExecutionMode.REDIS_WRITE_ATOMIC) { connectionFuture = connectionManager.connectionWriteOp(source, null); } else { diff --git a/redisson/src/main/java/org/redisson/connection/ConnectionManager.java b/redisson/src/main/java/org/redisson/connection/ConnectionManager.java index cb78e5c9b..6e4b60779 100644 --- a/redisson/src/main/java/org/redisson/connection/ConnectionManager.java +++ b/redisson/src/main/java/org/redisson/connection/ConnectionManager.java @@ -21,7 +21,6 @@ import io.netty.util.TimerTask; import io.netty.util.concurrent.Future; import org.redisson.ElementsSubscribeService; import org.redisson.api.NodeType; -import org.redisson.api.RFuture; import org.redisson.client.RedisClient; import org.redisson.client.RedisConnection; import org.redisson.client.RedisNodeNotFoundException; @@ -92,9 +91,9 @@ public interface ConnectionManager { void releaseWrite(NodeSource source, RedisConnection connection); - RFuture connectionReadOp(NodeSource source, RedisCommand command); + CompletableFuture connectionReadOp(NodeSource source, RedisCommand command); - RFuture connectionWriteOp(NodeSource source, RedisCommand command); + CompletableFuture connectionWriteOp(NodeSource source, RedisCommand command); RedisClient createClient(NodeType type, RedisURI address, int timeout, int commandTimeout, String sslHostname); diff --git a/redisson/src/main/java/org/redisson/connection/MasterSlaveConnectionManager.java b/redisson/src/main/java/org/redisson/connection/MasterSlaveConnectionManager.java index 84c6ef54c..e21ea8f5c 100644 --- a/redisson/src/main/java/org/redisson/connection/MasterSlaveConnectionManager.java +++ b/redisson/src/main/java/org/redisson/connection/MasterSlaveConnectionManager.java @@ -40,7 +40,6 @@ import io.netty.util.internal.PlatformDependent; import org.redisson.ElementsSubscribeService; import org.redisson.Version; import org.redisson.api.NodeType; -import org.redisson.api.RFuture; import org.redisson.client.*; import org.redisson.client.codec.Codec; import org.redisson.client.protocol.RedisCommand; @@ -48,7 +47,6 @@ import org.redisson.cluster.ClusterSlotRange; import org.redisson.config.*; import org.redisson.misc.InfinitySemaphoreLatch; import org.redisson.misc.RedisURI; -import org.redisson.misc.RedissonPromise; import org.redisson.pubsub.PublishSubscribeService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -504,10 +502,12 @@ public class MasterSlaveConnectionManager implements ConnectionManager { } @Override - public RFuture connectionWriteOp(NodeSource source, RedisCommand command) { + public CompletableFuture connectionWriteOp(NodeSource source, RedisCommand command) { MasterSlaveEntry entry = getEntry(source); if (entry == null) { - return RedissonPromise.newFailedFuture(createNodeNotFoundException(source)); + CompletableFuture f = new CompletableFuture<>(); + f.completeExceptionally(createNodeNotFoundException(source)); + return f; } // fix for https://github.com/redisson/redisson/issues/1548 if (source.getRedirect() != null @@ -534,10 +534,12 @@ public class MasterSlaveConnectionManager implements ConnectionManager { } @Override - public RFuture connectionReadOp(NodeSource source, RedisCommand command) { + public CompletableFuture connectionReadOp(NodeSource source, RedisCommand command) { MasterSlaveEntry entry = getEntry(source); if (entry == null) { - return RedissonPromise.newFailedFuture(createNodeNotFoundException(source)); + CompletableFuture f = new CompletableFuture<>(); + f.completeExceptionally(createNodeNotFoundException(source)); + return f; } if (source.getRedirect() != null) { diff --git a/redisson/src/main/java/org/redisson/connection/MasterSlaveEntry.java b/redisson/src/main/java/org/redisson/connection/MasterSlaveEntry.java index f787e6d4b..33a4c9b9a 100644 --- a/redisson/src/main/java/org/redisson/connection/MasterSlaveEntry.java +++ b/redisson/src/main/java/org/redisson/connection/MasterSlaveEntry.java @@ -17,7 +17,6 @@ package org.redisson.connection; import io.netty.channel.ChannelFuture; import org.redisson.api.NodeType; -import org.redisson.api.RFuture; import org.redisson.client.RedisClient; import org.redisson.client.RedisConnection; import org.redisson.client.RedisPubSubConnection; @@ -254,8 +253,8 @@ public class MasterSlaveEntry { return; } - RFuture newConnectionFuture = entry.connectionWriteOp(commandData.getCommand()); - newConnectionFuture.onComplete((newConnection, e) -> { + CompletableFuture newConnectionFuture = entry.connectionWriteOp(commandData.getCommand()); + newConnectionFuture.whenComplete((newConnection, e) -> { if (e != null) { connectionManager.newTimeout(timeout -> reattachBlockingQueue(commandData), 1, TimeUnit.SECONDS); @@ -274,7 +273,7 @@ public class MasterSlaveEntry { reattachBlockingQueue(commandData), 1, TimeUnit.SECONDS); } }); - commandData.getPromise().onComplete((r, ex) -> { + commandData.getPromise().whenComplete((r, ex) -> { entry.releaseWrite(newConnection); }); }); @@ -483,33 +482,33 @@ public class MasterSlaveEntry { return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); } - public RFuture connectionWriteOp(RedisCommand command) { + public CompletableFuture connectionWriteOp(RedisCommand command) { return writeConnectionPool.get(command); } - public RFuture redirectedConnectionWriteOp(RedisCommand command, RedisURI addr) { + public CompletableFuture redirectedConnectionWriteOp(RedisCommand command, RedisURI addr) { return slaveBalancer.getConnection(command, addr); } - public RFuture connectionReadOp(RedisCommand command) { + public CompletableFuture connectionReadOp(RedisCommand command) { if (config.getReadMode() == ReadMode.MASTER) { return connectionWriteOp(command); } return slaveBalancer.nextConnection(command); } - public RFuture connectionReadOp(RedisCommand command, RedisURI addr) { + public CompletableFuture connectionReadOp(RedisCommand command, RedisURI addr) { return slaveBalancer.getConnection(command, addr); } - public RFuture connectionReadOp(RedisCommand command, RedisClient client) { + public CompletableFuture connectionReadOp(RedisCommand command, RedisClient client) { if (config.getReadMode() == ReadMode.MASTER) { return connectionWriteOp(command); } return slaveBalancer.getConnection(command, client); } - public RFuture nextPubSubConnection() { + public CompletableFuture nextPubSubConnection() { if (config.getSubscriptionMode() == SubscriptionMode.MASTER) { return pubSubConnectionPool.get(); } diff --git a/redisson/src/main/java/org/redisson/connection/SingleEntry.java b/redisson/src/main/java/org/redisson/connection/SingleEntry.java index a7026574e..c9dfe2128 100644 --- a/redisson/src/main/java/org/redisson/connection/SingleEntry.java +++ b/redisson/src/main/java/org/redisson/connection/SingleEntry.java @@ -15,12 +15,13 @@ */ package org.redisson.connection; -import org.redisson.api.RFuture; import org.redisson.client.RedisConnection; import org.redisson.client.protocol.RedisCommand; import org.redisson.config.MasterSlaveServersConfig; import org.redisson.misc.RedisURI; +import java.util.concurrent.CompletableFuture; + /** * * @author Nikita Koksharov @@ -33,12 +34,12 @@ public class SingleEntry extends MasterSlaveEntry { } @Override - public RFuture connectionReadOp(RedisCommand command, RedisURI addr) { + public CompletableFuture connectionReadOp(RedisCommand command, RedisURI addr) { return super.connectionWriteOp(command); } @Override - public RFuture connectionReadOp(RedisCommand command) { + public CompletableFuture connectionReadOp(RedisCommand command) { return super.connectionWriteOp(command); } 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 6ceac54c9..83db86685 100644 --- a/redisson/src/main/java/org/redisson/connection/balancer/LoadBalancerManager.java +++ b/redisson/src/main/java/org/redisson/connection/balancer/LoadBalancerManager.java @@ -16,7 +16,6 @@ package org.redisson.connection.balancer; import org.redisson.api.NodeType; -import org.redisson.api.RFuture; import org.redisson.client.RedisClient; import org.redisson.client.RedisConnection; import org.redisson.client.RedisConnectionException; @@ -31,7 +30,6 @@ import org.redisson.connection.MasterSlaveEntry; import org.redisson.connection.pool.PubSubConnectionPool; import org.redisson.connection.pool.SlaveConnectionPool; import org.redisson.misc.RedisURI; -import org.redisson.misc.RedissonPromise; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -191,7 +189,7 @@ public class LoadBalancerManager { return connectionEntry; } - public RFuture nextPubSubConnection() { + public CompletableFuture nextPubSubConnection() { return pubSubConnectionPool.get(); } @@ -236,25 +234,29 @@ public class LoadBalancerManager { return client2Entry.get(redisClient); } - public RFuture getConnection(RedisCommand command, RedisURI addr) { + public CompletableFuture getConnection(RedisCommand command, RedisURI addr) { ClientConnectionsEntry entry = getEntry(addr); if (entry != null) { return slaveConnectionPool.get(command, entry); } RedisConnectionException exception = new RedisConnectionException("Can't find entry for " + addr); - return RedissonPromise.newFailedFuture(exception); + CompletableFuture f = new CompletableFuture<>(); + f.completeExceptionally(exception); + return f; } - public RFuture getConnection(RedisCommand command, RedisClient client) { + public CompletableFuture getConnection(RedisCommand command, RedisClient client) { ClientConnectionsEntry entry = getEntry(client); if (entry != null) { return slaveConnectionPool.get(command, entry); } RedisConnectionException exception = new RedisConnectionException("Can't find entry for " + client); - return RedissonPromise.newFailedFuture(exception); + CompletableFuture f = new CompletableFuture<>(); + f.completeExceptionally(exception); + return f; } - public RFuture nextConnection(RedisCommand command) { + public CompletableFuture nextConnection(RedisCommand command) { return slaveConnectionPool.get(command); } 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 069a3c880..028bac809 100644 --- a/redisson/src/main/java/org/redisson/connection/pool/ConnectionPool.java +++ b/redisson/src/main/java/org/redisson/connection/pool/ConnectionPool.java @@ -26,8 +26,6 @@ import org.redisson.connection.ClientConnectionsEntry; import org.redisson.connection.ClientConnectionsEntry.FreezeReason; import org.redisson.connection.ConnectionManager; import org.redisson.connection.MasterSlaveEntry; -import org.redisson.misc.RPromise; -import org.redisson.misc.RedissonPromise; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -112,9 +110,9 @@ abstract class ConnectionPool { @Override public void run() { - RPromise promise = new RedissonPromise(); + CompletableFuture promise = new CompletableFuture(); createConnection(entry, promise); - promise.onComplete((conn, e) -> { + promise.whenComplete((conn, e) -> { if (e == null) { if (!initPromise.isDone()) { entry.addConnection(conn); @@ -178,7 +176,7 @@ abstract class ConnectionPool { protected abstract int getMinimumIdleSize(ClientConnectionsEntry entry); - public RFuture get(RedisCommand command) { + public CompletableFuture get(RedisCommand command) { List entriesCopy = new LinkedList(entries); for (Iterator iterator = entriesCopy.iterator(); iterator.hasNext();) { ClientConnectionsEntry entry = iterator.next(); @@ -211,10 +209,12 @@ abstract class ConnectionPool { } RedisConnectionException exception = new RedisConnectionException(errorMsg.toString()); - return RedissonPromise.newFailedFuture(exception); + CompletableFuture result = new CompletableFuture<>(); + result.completeExceptionally(exception); + return result; } - public RFuture get(RedisCommand command, ClientConnectionsEntry entry) { + public CompletableFuture get(RedisCommand command, ClientConnectionsEntry entry) { return acquireConnection(command, entry); } @@ -222,8 +222,8 @@ abstract class ConnectionPool { } - protected final RFuture acquireConnection(RedisCommand command, ClientConnectionsEntry entry) { - RPromise result = new RedissonPromise(); + protected final CompletableFuture acquireConnection(RedisCommand command, ClientConnectionsEntry entry) { + CompletableFuture result = new CompletableFuture(); Runnable callback = () -> { connectTo(entry, result, command); @@ -248,7 +248,7 @@ abstract class ConnectionPool { return (CompletionStage) entry.connect(); } - private void connectTo(ClientConnectionsEntry entry, RPromise promise, RedisCommand command) { + private void connectTo(ClientConnectionsEntry entry, CompletableFuture promise, RedisCommand command) { if (promise.isDone()) { connectionManager.getGroup().submit(() -> { releaseConnection(entry); @@ -269,7 +269,7 @@ abstract class ConnectionPool { createConnection(entry, promise); } - private void createConnection(ClientConnectionsEntry entry, RPromise promise) { + private void createConnection(ClientConnectionsEntry entry, CompletableFuture promise) { CompletionStage connFuture = connect(entry); connFuture.whenComplete((conn, e) -> { if (e != null) { @@ -286,18 +286,18 @@ abstract class ConnectionPool { }); } - private void connectedSuccessful(ClientConnectionsEntry entry, RPromise promise, T conn) { + private void connectedSuccessful(ClientConnectionsEntry entry, CompletableFuture promise, T conn) { if (conn.isActive() && entry.getNodeType() == NodeType.SLAVE) { entry.resetFirstFail(); } - if (!promise.trySuccess(conn)) { + if (!promise.complete(conn)) { releaseConnection(entry, conn); releaseConnection(entry); } } - private void promiseFailure(ClientConnectionsEntry entry, RPromise promise, Throwable cause) { + private void promiseFailure(ClientConnectionsEntry entry, CompletableFuture promise, Throwable cause) { if (entry.getNodeType() == NodeType.SLAVE) { entry.trySetupFistFail(); if (entry.isFailed()) { @@ -307,10 +307,10 @@ abstract class ConnectionPool { releaseConnection(entry); - promise.tryFailure(cause); + promise.completeExceptionally(cause); } - private void promiseFailure(ClientConnectionsEntry entry, RPromise promise, T conn) { + private void promiseFailure(ClientConnectionsEntry entry, CompletableFuture promise, T conn) { if (entry.getNodeType() == NodeType.SLAVE) { entry.trySetupFistFail(); if (entry.isFailed()) { @@ -327,7 +327,7 @@ abstract class ConnectionPool { releaseConnection(entry); RedisConnectionException cause = new RedisConnectionException(conn + " is not active!"); - promise.tryFailure(cause); + promise.completeExceptionally(cause); } private void checkForReconnect(ClientConnectionsEntry entry, Throwable cause) { diff --git a/redisson/src/main/java/org/redisson/connection/pool/MasterConnectionPool.java b/redisson/src/main/java/org/redisson/connection/pool/MasterConnectionPool.java index d58b475c2..838060f6f 100644 --- a/redisson/src/main/java/org/redisson/connection/pool/MasterConnectionPool.java +++ b/redisson/src/main/java/org/redisson/connection/pool/MasterConnectionPool.java @@ -15,7 +15,6 @@ */ package org.redisson.connection.pool; -import org.redisson.api.RFuture; import org.redisson.client.RedisConnection; import org.redisson.client.protocol.RedisCommand; import org.redisson.config.MasterSlaveServersConfig; @@ -23,6 +22,8 @@ import org.redisson.connection.ClientConnectionsEntry; import org.redisson.connection.ConnectionManager; import org.redisson.connection.MasterSlaveEntry; +import java.util.concurrent.CompletableFuture; + /** * Connection pool for master node @@ -37,7 +38,7 @@ public class MasterConnectionPool extends ConnectionPool { } @Override - public RFuture get(RedisCommand command) { + public CompletableFuture get(RedisCommand command) { return acquireConnection(command, entries.peek()); } diff --git a/redisson/src/main/java/org/redisson/connection/pool/MasterPubSubConnectionPool.java b/redisson/src/main/java/org/redisson/connection/pool/MasterPubSubConnectionPool.java index 26893c28c..1d7acecf3 100644 --- a/redisson/src/main/java/org/redisson/connection/pool/MasterPubSubConnectionPool.java +++ b/redisson/src/main/java/org/redisson/connection/pool/MasterPubSubConnectionPool.java @@ -15,7 +15,6 @@ */ package org.redisson.connection.pool; -import org.redisson.api.RFuture; import org.redisson.client.RedisPubSubConnection; import org.redisson.client.protocol.RedisCommand; import org.redisson.config.MasterSlaveServersConfig; @@ -23,6 +22,8 @@ import org.redisson.connection.ClientConnectionsEntry; import org.redisson.connection.ConnectionManager; import org.redisson.connection.MasterSlaveEntry; +import java.util.concurrent.CompletableFuture; + /** * Connection pool for Publish/Subscribe used with single node * @@ -37,7 +38,7 @@ public class MasterPubSubConnectionPool extends PubSubConnectionPool { } @Override - public RFuture get(RedisCommand command) { + public CompletableFuture get(RedisCommand command) { return acquireConnection(command, entries.peek()); } diff --git a/redisson/src/main/java/org/redisson/connection/pool/PubSubConnectionPool.java b/redisson/src/main/java/org/redisson/connection/pool/PubSubConnectionPool.java index 9e1c23a1a..54330bd20 100644 --- a/redisson/src/main/java/org/redisson/connection/pool/PubSubConnectionPool.java +++ b/redisson/src/main/java/org/redisson/connection/pool/PubSubConnectionPool.java @@ -15,7 +15,6 @@ */ package org.redisson.connection.pool; -import org.redisson.api.RFuture; import org.redisson.client.RedisPubSubConnection; import org.redisson.client.protocol.RedisCommand; import org.redisson.client.protocol.RedisCommands; @@ -24,6 +23,7 @@ import org.redisson.connection.ClientConnectionsEntry; import org.redisson.connection.ConnectionManager; import org.redisson.connection.MasterSlaveEntry; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; /** @@ -38,7 +38,7 @@ public class PubSubConnectionPool extends ConnectionPool super(config, connectionManager, masterSlaveEntry); } - public RFuture get() { + public CompletableFuture get() { return get(RedisCommands.PUBLISH); } diff --git a/redisson/src/main/java/org/redisson/pubsub/CountDownLatchPubSub.java b/redisson/src/main/java/org/redisson/pubsub/CountDownLatchPubSub.java index 4e008fb75..0afd1f175 100644 --- a/redisson/src/main/java/org/redisson/pubsub/CountDownLatchPubSub.java +++ b/redisson/src/main/java/org/redisson/pubsub/CountDownLatchPubSub.java @@ -16,7 +16,8 @@ package org.redisson.pubsub; import org.redisson.RedissonCountDownLatchEntry; -import org.redisson.misc.RPromise; + +import java.util.concurrent.CompletableFuture; /** * @@ -33,7 +34,7 @@ public class CountDownLatchPubSub extends PublishSubscribe newPromise) { + protected RedissonCountDownLatchEntry createEntry(CompletableFuture newPromise) { return new RedissonCountDownLatchEntry(newPromise); } diff --git a/redisson/src/main/java/org/redisson/pubsub/LockPubSub.java b/redisson/src/main/java/org/redisson/pubsub/LockPubSub.java index f54d07dae..fcd8a77de 100644 --- a/redisson/src/main/java/org/redisson/pubsub/LockPubSub.java +++ b/redisson/src/main/java/org/redisson/pubsub/LockPubSub.java @@ -16,7 +16,8 @@ package org.redisson.pubsub; import org.redisson.RedissonLockEntry; -import org.redisson.misc.RPromise; + +import java.util.concurrent.CompletableFuture; /** * @@ -33,7 +34,7 @@ public class LockPubSub extends PublishSubscribe { } @Override - protected RedissonLockEntry createEntry(RPromise newPromise) { + protected RedissonLockEntry createEntry(CompletableFuture newPromise) { return new RedissonLockEntry(newPromise); } diff --git a/redisson/src/main/java/org/redisson/pubsub/PublishSubscribe.java b/redisson/src/main/java/org/redisson/pubsub/PublishSubscribe.java index efa5ae39f..555a7c8ad 100644 --- a/redisson/src/main/java/org/redisson/pubsub/PublishSubscribe.java +++ b/redisson/src/main/java/org/redisson/pubsub/PublishSubscribe.java @@ -16,16 +16,13 @@ package org.redisson.pubsub; import org.redisson.PubSubEntry; -import org.redisson.api.RFuture; import org.redisson.client.BaseRedisPubSubListener; import org.redisson.client.ChannelName; import org.redisson.client.RedisPubSubListener; import org.redisson.client.codec.LongCodec; import org.redisson.client.protocol.pubsub.PubSubType; -import org.redisson.misc.RPromise; -import org.redisson.misc.RedissonPromise; -import org.redisson.misc.TransferListener; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -64,21 +61,21 @@ abstract class PublishSubscribe> { } - public RFuture subscribe(String entryName, String channelName) { + public CompletableFuture subscribe(String entryName, String channelName) { AsyncSemaphore semaphore = service.getSemaphore(new ChannelName(channelName)); - RPromise newPromise = new RedissonPromise<>(); + CompletableFuture newPromise = new CompletableFuture<>(); semaphore.acquire(() -> { - if (!newPromise.setUncancellable()) { - semaphore.release(); - return; - } - E entry = entries.get(entryName); if (entry != null) { entry.acquire(); semaphore.release(); - entry.getPromise().onComplete(new TransferListener(newPromise)); - return; + entry.getPromise().whenComplete((r, e) -> { + if (e != null) { + newPromise.completeExceptionally(e); + return; + } + newPromise.complete(r); + }); } E value = createEntry(newPromise); @@ -88,7 +85,13 @@ abstract class PublishSubscribe> { if (oldValue != null) { oldValue.acquire(); semaphore.release(); - oldValue.getPromise().onComplete(new TransferListener(newPromise)); + oldValue.getPromise().whenComplete((r, e) -> { + if (e != null) { + newPromise.completeExceptionally(e); + return; + } + newPromise.complete(r); + }); return; } @@ -99,7 +102,7 @@ abstract class PublishSubscribe> { return newPromise; } - protected abstract E createEntry(RPromise newPromise); + protected abstract E createEntry(CompletableFuture newPromise); protected abstract void onMessage(E value, Long message); @@ -122,7 +125,7 @@ abstract class PublishSubscribe> { } if (type == PubSubType.SUBSCRIBE) { - value.getPromise().trySuccess(value); + value.getPromise().complete(value); return true; } return false; diff --git a/redisson/src/main/java/org/redisson/pubsub/PublishSubscribeService.java b/redisson/src/main/java/org/redisson/pubsub/PublishSubscribeService.java index ce96cf9b1..abea6086e 100644 --- a/redisson/src/main/java/org/redisson/pubsub/PublishSubscribeService.java +++ b/redisson/src/main/java/org/redisson/pubsub/PublishSubscribeService.java @@ -32,12 +32,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; /** * @@ -140,7 +138,7 @@ public class PublishSubscribeService { return name2PubSubConnection.get(createKey(channelName)); } - public RFuture> psubscribe(ChannelName channelName, Codec codec, RedisPubSubListener... listeners) { + public CompletableFuture> psubscribe(ChannelName channelName, Codec codec, RedisPubSubListener... listeners) { if (isMultiEntity(channelName)) { Collection entrySet = connectionManager.getEntrySet(); @@ -160,36 +158,19 @@ public class PublishSubscribeService { return l; }).toArray(RedisPubSubListener[]::new); - RPromise> result = new RedissonPromise<>(); - Collection entries = new ConcurrentLinkedQueue<>(); - AtomicInteger counter = new AtomicInteger(entrySet.size()); + List> futures = new ArrayList<>(); for (MasterSlaveEntry entry : entrySet) { - RFuture future = subscribe(PubSubType.PSUBSCRIBE, codec, channelName, entry, ls); - future.onComplete((res, e) -> { - if (e != null) { - result.tryFailure(e); - return; - } - entries.add(res); - if (counter.decrementAndGet() == 0) { - result.trySuccess(entries); - } - }); + CompletableFuture future = subscribe(PubSubType.PSUBSCRIBE, codec, channelName, entry, ls); + futures.add(future); } - return result; + CompletableFuture future = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); + return future.thenApply(r -> { + return futures.stream().map(v -> v.getNow(null)).collect(Collectors.toList()); + }); } - RPromise> result = new RedissonPromise<>(); - RFuture f = subscribe(PubSubType.PSUBSCRIBE, codec, channelName, getEntry(channelName), listeners); - f.onComplete((res, e) -> { - if (e != null) { - result.tryFailure(e); - return; - } - - result.trySuccess(Collections.singletonList(res)); - }); - return result; + CompletableFuture f = subscribe(PubSubType.PSUBSCRIBE, codec, channelName, getEntry(channelName), listeners); + return f.thenApply(res -> Collections.singletonList(res)); } private boolean isMultiEntity(ChannelName channelName) { @@ -198,12 +179,12 @@ public class PublishSubscribeService { || channelName.toString().startsWith("__keyevent@")); } - public RFuture subscribe(Codec codec, ChannelName channelName, RedisPubSubListener... listeners) { + public CompletableFuture subscribe(Codec codec, ChannelName channelName, RedisPubSubListener... listeners) { return subscribe(PubSubType.SUBSCRIBE, codec, channelName, getEntry(channelName), listeners); } - private RFuture subscribe(PubSubType type, Codec codec, ChannelName channelName, MasterSlaveEntry entry, RedisPubSubListener... listeners) { - RPromise promise = new RedissonPromise<>(); + private CompletableFuture subscribe(PubSubType type, Codec codec, ChannelName channelName, MasterSlaveEntry entry, RedisPubSubListener... listeners) { + CompletableFuture promise = new CompletableFuture<>(); AsyncSemaphore lock = getSemaphore(channelName); lock.acquire(() -> { if (promise.isDone()) { @@ -216,8 +197,8 @@ public class PublishSubscribeService { return promise; } - public RFuture subscribe(Codec codec, String channelName, AsyncSemaphore semaphore, RedisPubSubListener... listeners) { - RPromise promise = new RedissonPromise<>(); + public CompletableFuture subscribe(Codec codec, String channelName, AsyncSemaphore semaphore, RedisPubSubListener... listeners) { + CompletableFuture promise = new CompletableFuture<>(); subscribe(codec, new ChannelName(channelName), getEntry(new ChannelName(channelName)), promise, PubSubType.SUBSCRIBE, semaphore, listeners); return promise; } @@ -232,7 +213,7 @@ public class PublishSubscribeService { } private void subscribe(Codec codec, ChannelName channelName, MasterSlaveEntry entry, - RPromise promise, PubSubType type, + CompletableFuture promise, PubSubType type, AsyncSemaphore lock, RedisPubSubListener... listeners) { PubSubConnectionEntry connEntry = name2PubSubConnection.get(new PubSubKey(channelName, entry)); if (connEntry != null) { @@ -277,7 +258,7 @@ public class PublishSubscribeService { } freePubSubLock.release(); - RFuture subscribeFuture = addListeners(channelName, promise, type, lock, freeEntry, listeners); + CompletableFuture subscribeFuture = addListeners(channelName, promise, type, lock, freeEntry, listeners); ChannelFuture future; if (PubSubType.PSUBSCRIBE == type) { @@ -306,17 +287,17 @@ public class PublishSubscribeService { return connectionManager.getEntry(slot); } - private RFuture addListeners(ChannelName channelName, RPromise promise, + private CompletableFuture addListeners(ChannelName channelName, CompletableFuture promise, PubSubType type, AsyncSemaphore lock, PubSubConnectionEntry connEntry, RedisPubSubListener... listeners) { for (RedisPubSubListener listener : listeners) { connEntry.addListener(channelName, listener); } SubscribeListener list = connEntry.getSubscribeFuture(channelName, type); - RFuture subscribeFuture = list.getSuccessFuture(); + CompletableFuture subscribeFuture = list.getSuccessFuture(); - subscribeFuture.onComplete((res, e) -> { - if (!promise.trySuccess(connEntry)) { + return subscribeFuture.whenComplete((res, e) -> { + if (!promise.complete(connEntry)) { for (RedisPubSubListener listener : listeners) { connEntry.removeListener(channelName, listener); } @@ -332,31 +313,31 @@ public class PublishSubscribeService { lock.release(); } }); - - return subscribeFuture; } - private RFuture nextPubSubConnection(MasterSlaveEntry entry, ChannelName channelName) { + private CompletionStage 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."); - return RedissonPromise.newFailedFuture(ex); + CompletableFuture result = new CompletableFuture<>(); + result.completeExceptionally(ex); + return result; } return entry.nextPubSubConnection(); } private void connect(Codec codec, ChannelName channelName, - MasterSlaveEntry msEntry, RPromise promise, PubSubType type, AsyncSemaphore lock, RedisPubSubListener... listeners) { - RFuture connFuture = nextPubSubConnection(msEntry, channelName); - promise.onComplete((res, e) -> { + MasterSlaveEntry msEntry, CompletableFuture promise, PubSubType type, AsyncSemaphore lock, RedisPubSubListener... listeners) { + CompletionStage connFuture = nextPubSubConnection(msEntry, channelName); + promise.whenComplete((res, e) -> { if (e != null) { ((RPromise) connFuture).tryFailure(e); } }); - connFuture.onComplete((conn, ex) -> { + connFuture.whenComplete((conn, ex) -> { if (ex != null) { lock.release(); - promise.tryFailure(ex); + promise.completeExceptionally(ex); return; } @@ -380,7 +361,7 @@ public class PublishSubscribeService { } freePubSubLock.release(); - RFuture subscribeFuture = addListeners(channelName, promise, type, lock, entry, listeners); + addListeners(channelName, promise, type, lock, entry, listeners); ChannelFuture future; if (PubSubType.PSUBSCRIBE == type) { @@ -392,13 +373,13 @@ public class PublishSubscribeService { future.addListener((ChannelFutureListener) future1 -> { if (!future1.isSuccess()) { if (!promise.isDone()) { - subscribeFuture.cancel(false); + promise.cancel(false); } return; } connectionManager.newTimeout(timeout -> - subscribeFuture.cancel(false), + promise.cancel(false), config.getTimeout(), TimeUnit.MILLISECONDS); }); }); @@ -611,8 +592,8 @@ public class PublishSubscribeService { private void subscribe(ChannelName channelName, Collection> listeners, Codec subscribeCodec) { - RFuture subscribeFuture = subscribe(subscribeCodec, channelName, listeners.toArray(new RedisPubSubListener[0])); - subscribeFuture.onComplete((res, e) -> { + CompletableFuture subscribeFuture = subscribe(subscribeCodec, channelName, listeners.toArray(new RedisPubSubListener[0])); + subscribeFuture.whenComplete((res, e) -> { if (e != null) { connectionManager.newTimeout(task -> { subscribe(channelName, listeners, subscribeCodec); @@ -626,9 +607,9 @@ public class PublishSubscribeService { private void psubscribe(ChannelName channelName, Collection> listeners, Codec subscribeCodec) { - RFuture> subscribeFuture = + CompletableFuture> subscribeFuture = psubscribe(channelName, subscribeCodec, listeners.toArray(new RedisPubSubListener[0])); - subscribeFuture.onComplete((res, e) -> { + subscribeFuture.whenComplete((res, e) -> { if (e != null) { connectionManager.newTimeout(task -> { psubscribe(channelName, listeners, subscribeCodec); @@ -640,8 +621,8 @@ public class PublishSubscribeService { }); } - public RFuture removeListenerAsync(PubSubType type, ChannelName channelName, EventListener listener) { - RPromise promise = new RedissonPromise<>(); + public CompletableFuture removeListenerAsync(PubSubType type, ChannelName channelName, EventListener listener) { + CompletableFuture promise = new CompletableFuture<>(); AsyncSemaphore semaphore = getSemaphore(channelName); semaphore.acquire(() -> { Collection entries = Collections.singletonList(getEntry(channelName)); @@ -655,7 +636,7 @@ public class PublishSubscribeService { if (entry == null) { if (counter.decrementAndGet() == 0) { semaphore.release(); - promise.trySuccess(null); + promise.complete(null); } continue; } @@ -666,13 +647,13 @@ public class PublishSubscribeService { .onComplete((r, ex) -> { if (counter.decrementAndGet() == 0) { semaphore.release(); - promise.trySuccess(null); + promise.complete(null); } }); } else { if (counter.decrementAndGet() == 0) { semaphore.release(); - promise.trySuccess(null); + promise.complete(null); } } } @@ -680,8 +661,8 @@ public class PublishSubscribeService { return promise; } - public RFuture removeListenerAsync(PubSubType type, ChannelName channelName, Integer... listenerIds) { - RPromise promise = new RedissonPromise<>(); + public CompletableFuture removeListenerAsync(PubSubType type, ChannelName channelName, Integer... listenerIds) { + CompletableFuture promise = new CompletableFuture<>(); AsyncSemaphore semaphore = getSemaphore(channelName); semaphore.acquire(() -> { Collection entries = Collections.singletonList(getEntry(channelName)); @@ -695,7 +676,7 @@ public class PublishSubscribeService { if (entry == null) { if (counter.decrementAndGet() == 0) { semaphore.release(); - promise.trySuccess(null); + promise.complete(null); } continue; } @@ -708,13 +689,13 @@ public class PublishSubscribeService { .onComplete((r, ex) -> { if (counter.decrementAndGet() == 0) { semaphore.release(); - promise.trySuccess(null); + promise.complete(null); } }); } else { if (counter.decrementAndGet() == 0) { semaphore.release(); - promise.trySuccess(null); + promise.complete(null); } } } diff --git a/redisson/src/main/java/org/redisson/pubsub/SemaphorePubSub.java b/redisson/src/main/java/org/redisson/pubsub/SemaphorePubSub.java index e4fe6ae2a..5c830c4fa 100644 --- a/redisson/src/main/java/org/redisson/pubsub/SemaphorePubSub.java +++ b/redisson/src/main/java/org/redisson/pubsub/SemaphorePubSub.java @@ -16,7 +16,8 @@ package org.redisson.pubsub; import org.redisson.RedissonLockEntry; -import org.redisson.misc.RPromise; + +import java.util.concurrent.CompletableFuture; /** * @@ -30,7 +31,7 @@ public class SemaphorePubSub extends PublishSubscribe { } @Override - protected RedissonLockEntry createEntry(RPromise newPromise) { + protected RedissonLockEntry createEntry(CompletableFuture newPromise) { return new RedissonLockEntry(newPromise); } diff --git a/redisson/src/main/java/org/redisson/reactive/CommandReactiveBatchService.java b/redisson/src/main/java/org/redisson/reactive/CommandReactiveBatchService.java index 2c7c543b5..dd71e9d26 100644 --- a/redisson/src/main/java/org/redisson/reactive/CommandReactiveBatchService.java +++ b/redisson/src/main/java/org/redisson/reactive/CommandReactiveBatchService.java @@ -24,10 +24,10 @@ import org.redisson.command.CommandBatchService; import org.redisson.connection.ConnectionManager; import org.redisson.connection.NodeSource; import org.redisson.liveobject.core.RedissonObjectBuilder; -import org.redisson.misc.RPromise; import reactor.core.publisher.Mono; import java.util.concurrent.Callable; +import java.util.concurrent.CompletableFuture; /** * @@ -64,14 +64,14 @@ public class CommandReactiveBatchService extends CommandReactiveService { } @Override - protected RPromise createPromise() { + protected CompletableFuture createPromise() { return batchService.createPromise(); } @Override - public void async(boolean readOnlyMode, NodeSource nodeSource, - Codec codec, RedisCommand command, Object[] params, RPromise mainPromise, boolean ignoreRedirect, boolean noRetry) { - batchService.async(readOnlyMode, nodeSource, codec, command, params, mainPromise, ignoreRedirect, noRetry); + public RFuture async(boolean readOnlyMode, NodeSource nodeSource, + Codec codec, RedisCommand command, Object[] params, boolean ignoreRedirect, boolean noRetry) { + return batchService.async(readOnlyMode, nodeSource, codec, command, params, ignoreRedirect, noRetry); } public RFuture> executeAsync() { diff --git a/redisson/src/main/java/org/redisson/rx/CommandRxBatchService.java b/redisson/src/main/java/org/redisson/rx/CommandRxBatchService.java index 886a93984..a5379bbb6 100644 --- a/redisson/src/main/java/org/redisson/rx/CommandRxBatchService.java +++ b/redisson/src/main/java/org/redisson/rx/CommandRxBatchService.java @@ -26,9 +26,9 @@ import org.redisson.command.CommandBatchService; import org.redisson.connection.ConnectionManager; import org.redisson.connection.NodeSource; import org.redisson.liveobject.core.RedissonObjectBuilder; -import org.redisson.misc.RPromise; import java.util.concurrent.Callable; +import java.util.concurrent.CompletableFuture; /** * @@ -65,14 +65,14 @@ public class CommandRxBatchService extends CommandRxService { } @Override - protected RPromise createPromise() { + protected CompletableFuture createPromise() { return batchService.createPromise(); } @Override - public void async(boolean readOnlyMode, NodeSource nodeSource, - Codec codec, RedisCommand command, Object[] params, RPromise mainPromise, boolean ignoreRedirect, boolean noRetry) { - batchService.async(readOnlyMode, nodeSource, codec, command, params, mainPromise, ignoreRedirect, noRetry); + public RFuture async(boolean readOnlyMode, NodeSource nodeSource, + Codec codec, RedisCommand command, Object[] params, boolean ignoreRedirect, boolean noRetry) { + return batchService.async(readOnlyMode, nodeSource, codec, command, params, ignoreRedirect, noRetry); } public RFuture> executeAsync() { diff --git a/redisson/src/test/java/org/redisson/RedisClientTest.java b/redisson/src/test/java/org/redisson/RedisClientTest.java index 923713d4a..daba803fb 100644 --- a/redisson/src/test/java/org/redisson/RedisClientTest.java +++ b/redisson/src/test/java/org/redisson/RedisClientTest.java @@ -137,7 +137,7 @@ public class RedisClientTest { CommandData cmd4 = conn.create(null, RedisCommands.PING); commands.add(cmd4); - RPromise p = new RedissonPromise(); + CompletableFuture p = new CompletableFuture(); conn.send(new CommandsData(p, commands, false, false)); assertThat(cmd1.getPromise().get()).isEqualTo("PONG"); @@ -172,7 +172,7 @@ public class RedisClientTest { commands.add(cmd1); } - RPromise p = new RedissonPromise(); + CompletableFuture p = new CompletableFuture(); conn.send(new CommandsData(p, commands, false, false)); for (CommandData commandData : commands) { diff --git a/redisson/src/test/java/org/redisson/RedissonBatchTest.java b/redisson/src/test/java/org/redisson/RedissonBatchTest.java index a46a999ef..ee4607655 100644 --- a/redisson/src/test/java/org/redisson/RedissonBatchTest.java +++ b/redisson/src/test/java/org/redisson/RedissonBatchTest.java @@ -422,7 +422,7 @@ public class RedissonBatchTest extends BaseTest { for (int i = 0; i < total; i++) { RFuture f = map.putAsync("" + i, "" + i, 5, TimeUnit.MINUTES); if (batchOptions.getExecutionMode() == ExecutionMode.REDIS_WRITE_ATOMIC) { - ((BatchPromise)f).getSentPromise().toCompletableFuture().join(); + ((BatchPromise)f.toCompletableFuture()).getSentPromise().join(); } }