Improvement - Virtual Threads compatibility #5499

pull/5520/head
Nikita Koksharov 1 year ago
parent 4d609c061a
commit 89ceaad0be

@ -33,6 +33,7 @@ import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
@ -45,20 +46,17 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
public static class ListenableCounter {
private int state;
private final AtomicInteger state = new AtomicInteger();
private Runnable r;
public synchronized void acquire() {
state++;
public void acquire() {
state.incrementAndGet();
}
public void release() {
synchronized (this) {
state--;
if (state != 0) {
if (state.decrementAndGet() != 0) {
return;
}
}
if (r != null) {
r.run();
@ -66,13 +64,11 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
}
}
public synchronized void addListener(Runnable r) {
synchronized (this) {
if (state != 0) {
public void addListener(Runnable r) {
if (state.get() != 0) {
this.r = r;
return;
}
}
r.run();
}
@ -108,7 +104,6 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
});
return Mono.fromFuture(future);
});
}
protected ChannelName toChannelName(ByteBuffer channel) {
@ -149,17 +144,13 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
ChannelName cn = toChannelName(channel);
CompletableFuture<Codec> f = subscribeService.unsubscribe(cn, PubSubType.UNSUBSCRIBE);
f = f.whenComplete((res, e) -> {
synchronized (RedissonReactiveSubscription.this.channels) {
Collection<PubSubConnectionEntry> entries = RedissonReactiveSubscription.this.channels.get(cn);
for (PubSubConnectionEntry entry : entries) {
if (!entry.hasListeners(cn)) {
entries.remove(entry);
RedissonReactiveSubscription.this.channels.computeIfPresent(cn, (key, entries) -> {
entries.removeIf(entry -> !entry.hasListeners(cn));
if (entries.isEmpty()) {
RedissonReactiveSubscription.this.channels.remove(cn);
}
}
}
return null;
}
return entries;
});
});
futures.add(f);
}
@ -186,12 +177,13 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
ChannelName cn = toChannelName(channel);
CompletableFuture<Codec> f = subscribeService.unsubscribe(cn, PubSubType.PUNSUBSCRIBE);
f = f.whenComplete((res, e) -> {
synchronized (RedissonReactiveSubscription.this.patterns) {
Collection<PubSubConnectionEntry> entries = RedissonReactiveSubscription.this.patterns.get(cn);
entries.stream()
.filter(en -> en.hasListeners(cn))
.forEach(ee -> RedissonReactiveSubscription.this.patterns.remove(cn));
RedissonReactiveSubscription.this.patterns.computeIfPresent(cn, (key, entries) -> {
entries.removeIf(entry -> !entry.hasListeners(cn));
if (entries.isEmpty()) {
return null;
}
return entries;
});
});
futures.add(f);
}

@ -33,6 +33,7 @@ import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
@ -45,20 +46,17 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
public static class ListenableCounter {
private int state;
private final AtomicInteger state = new AtomicInteger();
private Runnable r;
public synchronized void acquire() {
state++;
public void acquire() {
state.incrementAndGet();
}
public void release() {
synchronized (this) {
state--;
if (state != 0) {
if (state.decrementAndGet() != 0) {
return;
}
}
if (r != null) {
r.run();
@ -66,13 +64,11 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
}
}
public synchronized void addListener(Runnable r) {
synchronized (this) {
if (state != 0) {
public void addListener(Runnable r) {
if (state.get() != 0) {
this.r = r;
return;
}
}
r.run();
}
@ -148,17 +144,13 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
ChannelName cn = toChannelName(channel);
CompletableFuture<Codec> f = subscribeService.unsubscribe(cn, PubSubType.UNSUBSCRIBE);
f = f.whenComplete((res, e) -> {
synchronized (RedissonReactiveSubscription.this.channels) {
Collection<PubSubConnectionEntry> entries = RedissonReactiveSubscription.this.channels.get(cn);
for (PubSubConnectionEntry entry : entries) {
if (!entry.hasListeners(cn)) {
entries.remove(entry);
RedissonReactiveSubscription.this.channels.computeIfPresent(cn, (key, entries) -> {
entries.removeIf(entry -> !entry.hasListeners(cn));
if (entries.isEmpty()) {
RedissonReactiveSubscription.this.channels.remove(cn);
}
}
}
return null;
}
return entries;
});
});
futures.add(f);
}
@ -185,12 +177,13 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
ChannelName cn = toChannelName(channel);
CompletableFuture<Codec> f = subscribeService.unsubscribe(cn, PubSubType.PUNSUBSCRIBE);
f = f.whenComplete((res, e) -> {
synchronized (RedissonReactiveSubscription.this.patterns) {
Collection<PubSubConnectionEntry> entries = RedissonReactiveSubscription.this.patterns.get(cn);
entries.stream()
.filter(en -> en.hasListeners(cn))
.forEach(ee -> RedissonReactiveSubscription.this.patterns.remove(cn));
RedissonReactiveSubscription.this.patterns.computeIfPresent(cn, (key, entries) -> {
entries.removeIf(entry -> !entry.hasListeners(cn));
if (entries.isEmpty()) {
return null;
}
return entries;
});
});
futures.add(f);
}

@ -33,6 +33,7 @@ import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
@ -45,20 +46,17 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
public static class ListenableCounter {
private int state;
private final AtomicInteger state = new AtomicInteger();
private Runnable r;
public synchronized void acquire() {
state++;
public void acquire() {
state.incrementAndGet();
}
public void release() {
synchronized (this) {
state--;
if (state != 0) {
if (state.decrementAndGet() != 0) {
return;
}
}
if (r != null) {
r.run();
@ -66,13 +64,11 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
}
}
public synchronized void addListener(Runnable r) {
synchronized (this) {
if (state != 0) {
public void addListener(Runnable r) {
if (state.get() != 0) {
this.r = r;
return;
}
}
r.run();
}
@ -148,17 +144,13 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
ChannelName cn = toChannelName(channel);
CompletableFuture<Codec> f = subscribeService.unsubscribe(cn, PubSubType.UNSUBSCRIBE);
f = f.whenComplete((res, e) -> {
synchronized (RedissonReactiveSubscription.this.channels) {
Collection<PubSubConnectionEntry> entries = RedissonReactiveSubscription.this.channels.get(cn);
for (PubSubConnectionEntry entry : entries) {
if (!entry.hasListeners(cn)) {
entries.remove(entry);
RedissonReactiveSubscription.this.channels.computeIfPresent(cn, (key, entries) -> {
entries.removeIf(entry -> !entry.hasListeners(cn));
if (entries.isEmpty()) {
RedissonReactiveSubscription.this.channels.remove(cn);
}
}
}
return null;
}
return entries;
});
});
futures.add(f);
}
@ -185,12 +177,13 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
ChannelName cn = toChannelName(channel);
CompletableFuture<Codec> f = subscribeService.unsubscribe(cn, PubSubType.PUNSUBSCRIBE);
f = f.whenComplete((res, e) -> {
synchronized (RedissonReactiveSubscription.this.patterns) {
Collection<PubSubConnectionEntry> entries = RedissonReactiveSubscription.this.patterns.get(cn);
entries.stream()
.filter(en -> en.hasListeners(cn))
.forEach(ee -> RedissonReactiveSubscription.this.patterns.remove(cn));
RedissonReactiveSubscription.this.patterns.computeIfPresent(cn, (key, entries) -> {
entries.removeIf(entry -> !entry.hasListeners(cn));
if (entries.isEmpty()) {
return null;
}
return entries;
});
});
futures.add(f);
}

@ -33,6 +33,7 @@ import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
@ -45,20 +46,17 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
public static class ListenableCounter {
private int state;
private final AtomicInteger state = new AtomicInteger();
private Runnable r;
public synchronized void acquire() {
state++;
public void acquire() {
state.incrementAndGet();
}
public void release() {
synchronized (this) {
state--;
if (state != 0) {
if (state.decrementAndGet() != 0) {
return;
}
}
if (r != null) {
r.run();
@ -66,13 +64,11 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
}
}
public synchronized void addListener(Runnable r) {
synchronized (this) {
if (state != 0) {
public void addListener(Runnable r) {
if (state.get() != 0) {
this.r = r;
return;
}
}
r.run();
}
@ -148,17 +144,13 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
ChannelName cn = toChannelName(channel);
CompletableFuture<Codec> f = subscribeService.unsubscribe(cn, PubSubType.UNSUBSCRIBE);
f = f.whenComplete((res, e) -> {
synchronized (RedissonReactiveSubscription.this.channels) {
Collection<PubSubConnectionEntry> entries = RedissonReactiveSubscription.this.channels.get(cn);
for (PubSubConnectionEntry entry : entries) {
if (!entry.hasListeners(cn)) {
entries.remove(entry);
RedissonReactiveSubscription.this.channels.computeIfPresent(cn, (key, entries) -> {
entries.removeIf(entry -> !entry.hasListeners(cn));
if (entries.isEmpty()) {
RedissonReactiveSubscription.this.channels.remove(cn);
}
}
}
return null;
}
return entries;
});
});
futures.add(f);
}
@ -185,12 +177,13 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
ChannelName cn = toChannelName(channel);
CompletableFuture<Codec> f = subscribeService.unsubscribe(cn, PubSubType.PUNSUBSCRIBE);
f = f.whenComplete((res, e) -> {
synchronized (RedissonReactiveSubscription.this.patterns) {
Collection<PubSubConnectionEntry> entries = RedissonReactiveSubscription.this.patterns.get(cn);
entries.stream()
.filter(en -> en.hasListeners(cn))
.forEach(ee -> RedissonReactiveSubscription.this.patterns.remove(cn));
RedissonReactiveSubscription.this.patterns.computeIfPresent(cn, (key, entries) -> {
entries.removeIf(entry -> !entry.hasListeners(cn));
if (entries.isEmpty()) {
return null;
}
return entries;
});
});
futures.add(f);
}

@ -33,6 +33,7 @@ import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
@ -45,20 +46,17 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
public static class ListenableCounter {
private int state;
private final AtomicInteger state = new AtomicInteger();
private Runnable r;
public synchronized void acquire() {
state++;
public void acquire() {
state.incrementAndGet();
}
public void release() {
synchronized (this) {
state--;
if (state != 0) {
if (state.decrementAndGet() != 0) {
return;
}
}
if (r != null) {
r.run();
@ -66,13 +64,11 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
}
}
public synchronized void addListener(Runnable r) {
synchronized (this) {
if (state != 0) {
public void addListener(Runnable r) {
if (state.get() != 0) {
this.r = r;
return;
}
}
r.run();
}
@ -148,17 +144,13 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
ChannelName cn = toChannelName(channel);
CompletableFuture<Codec> f = subscribeService.unsubscribe(cn, PubSubType.UNSUBSCRIBE);
f = f.whenComplete((res, e) -> {
synchronized (RedissonReactiveSubscription.this.channels) {
Collection<PubSubConnectionEntry> entries = RedissonReactiveSubscription.this.channels.get(cn);
for (PubSubConnectionEntry entry : entries) {
if (!entry.hasListeners(cn)) {
entries.remove(entry);
RedissonReactiveSubscription.this.channels.computeIfPresent(cn, (key, entries) -> {
entries.removeIf(entry -> !entry.hasListeners(cn));
if (entries.isEmpty()) {
RedissonReactiveSubscription.this.channels.remove(cn);
}
}
}
return null;
}
return entries;
});
});
futures.add(f);
}
@ -185,12 +177,13 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
ChannelName cn = toChannelName(channel);
CompletableFuture<Codec> f = subscribeService.unsubscribe(cn, PubSubType.PUNSUBSCRIBE);
f = f.whenComplete((res, e) -> {
synchronized (RedissonReactiveSubscription.this.patterns) {
Collection<PubSubConnectionEntry> entries = RedissonReactiveSubscription.this.patterns.get(cn);
entries.stream()
.filter(en -> en.hasListeners(cn))
.forEach(ee -> RedissonReactiveSubscription.this.patterns.remove(cn));
RedissonReactiveSubscription.this.patterns.computeIfPresent(cn, (key, entries) -> {
entries.removeIf(entry -> !entry.hasListeners(cn));
if (entries.isEmpty()) {
return null;
}
return entries;
});
});
futures.add(f);
}

@ -36,6 +36,7 @@ import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
@ -48,20 +49,17 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
public static class ListenableCounter {
private int state;
private final AtomicInteger state = new AtomicInteger();
private Runnable r;
public synchronized void acquire() {
state++;
public void acquire() {
state.incrementAndGet();
}
public void release() {
synchronized (this) {
state--;
if (state != 0) {
if (state.decrementAndGet() != 0) {
return;
}
}
if (r != null) {
r.run();
@ -69,13 +67,11 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
}
}
public synchronized void addListener(Runnable r) {
synchronized (this) {
if (state != 0) {
public void addListener(Runnable r) {
if (state.get() != 0) {
this.r = r;
return;
}
}
r.run();
}
@ -175,17 +171,13 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
ChannelName cn = toChannelName(channel);
CompletableFuture<Codec> f = subscribeService.unsubscribe(cn, PubSubType.UNSUBSCRIBE);
f = f.whenComplete((res, e) -> {
synchronized (RedissonReactiveSubscription.this.channels) {
Collection<PubSubConnectionEntry> entries = RedissonReactiveSubscription.this.channels.get(cn);
for (PubSubConnectionEntry entry : entries) {
if (!entry.hasListeners(cn)) {
entries.remove(entry);
RedissonReactiveSubscription.this.channels.computeIfPresent(cn, (key, entries) -> {
entries.removeIf(entry -> !entry.hasListeners(cn));
if (entries.isEmpty()) {
RedissonReactiveSubscription.this.channels.remove(cn);
}
}
}
return null;
}
return entries;
});
});
futures.add(f);
}
@ -212,12 +204,13 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
ChannelName cn = toChannelName(channel);
CompletableFuture<Codec> f = subscribeService.unsubscribe(cn, PubSubType.PUNSUBSCRIBE);
f = f.whenComplete((res, e) -> {
synchronized (RedissonReactiveSubscription.this.patterns) {
Collection<PubSubConnectionEntry> entries = RedissonReactiveSubscription.this.patterns.get(cn);
entries.stream()
.filter(en -> en.hasListeners(cn))
.forEach(ee -> RedissonReactiveSubscription.this.patterns.remove(cn));
RedissonReactiveSubscription.this.patterns.computeIfPresent(cn, (key, entries) -> {
entries.removeIf(entry -> !entry.hasListeners(cn));
if (entries.isEmpty()) {
return null;
}
return entries;
});
});
futures.add(f);
}

@ -36,6 +36,7 @@ import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
@ -48,20 +49,17 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
public static class ListenableCounter {
private int state;
private final AtomicInteger state = new AtomicInteger();
private Runnable r;
public synchronized void acquire() {
state++;
public void acquire() {
state.incrementAndGet();
}
public void release() {
synchronized (this) {
state--;
if (state != 0) {
if (state.decrementAndGet() != 0) {
return;
}
}
if (r != null) {
r.run();
@ -69,13 +67,11 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
}
}
public synchronized void addListener(Runnable r) {
synchronized (this) {
if (state != 0) {
public void addListener(Runnable r) {
if (state.get() != 0) {
this.r = r;
return;
}
}
r.run();
}
@ -175,17 +171,13 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
ChannelName cn = toChannelName(channel);
CompletableFuture<Codec> f = subscribeService.unsubscribe(cn, PubSubType.UNSUBSCRIBE);
f = f.whenComplete((res, e) -> {
synchronized (RedissonReactiveSubscription.this.channels) {
Collection<PubSubConnectionEntry> entries = RedissonReactiveSubscription.this.channels.get(cn);
for (PubSubConnectionEntry entry : entries) {
if (!entry.hasListeners(cn)) {
entries.remove(entry);
RedissonReactiveSubscription.this.channels.computeIfPresent(cn, (key, entries) -> {
entries.removeIf(entry -> !entry.hasListeners(cn));
if (entries.isEmpty()) {
RedissonReactiveSubscription.this.channels.remove(cn);
}
}
}
return null;
}
return entries;
});
});
futures.add(f);
}
@ -212,12 +204,13 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
ChannelName cn = toChannelName(channel);
CompletableFuture<Codec> f = subscribeService.unsubscribe(cn, PubSubType.PUNSUBSCRIBE);
f = f.whenComplete((res, e) -> {
synchronized (RedissonReactiveSubscription.this.patterns) {
Collection<PubSubConnectionEntry> entries = RedissonReactiveSubscription.this.patterns.get(cn);
entries.stream()
.filter(en -> en.hasListeners(cn))
.forEach(ee -> RedissonReactiveSubscription.this.patterns.remove(cn));
RedissonReactiveSubscription.this.patterns.computeIfPresent(cn, (key, entries) -> {
entries.removeIf(entry -> !entry.hasListeners(cn));
if (entries.isEmpty()) {
return null;
}
return entries;
});
});
futures.add(f);
}

@ -36,6 +36,7 @@ import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
@ -48,20 +49,17 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
public static class ListenableCounter {
private int state;
private final AtomicInteger state = new AtomicInteger();
private Runnable r;
public synchronized void acquire() {
state++;
public void acquire() {
state.incrementAndGet();
}
public void release() {
synchronized (this) {
state--;
if (state != 0) {
if (state.decrementAndGet() != 0) {
return;
}
}
if (r != null) {
r.run();
@ -69,13 +67,11 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
}
}
public synchronized void addListener(Runnable r) {
synchronized (this) {
if (state != 0) {
public void addListener(Runnable r) {
if (state.get() != 0) {
this.r = r;
return;
}
}
r.run();
}
@ -175,17 +171,13 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
ChannelName cn = toChannelName(channel);
CompletableFuture<Codec> f = subscribeService.unsubscribe(cn, PubSubType.UNSUBSCRIBE);
f = f.whenComplete((res, e) -> {
synchronized (RedissonReactiveSubscription.this.channels) {
Collection<PubSubConnectionEntry> entries = RedissonReactiveSubscription.this.channels.get(cn);
for (PubSubConnectionEntry entry : entries) {
if (!entry.hasListeners(cn)) {
entries.remove(entry);
RedissonReactiveSubscription.this.channels.computeIfPresent(cn, (key, entries) -> {
entries.removeIf(entry -> !entry.hasListeners(cn));
if (entries.isEmpty()) {
RedissonReactiveSubscription.this.channels.remove(cn);
}
}
}
return null;
}
return entries;
});
});
futures.add(f);
}
@ -212,12 +204,13 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
ChannelName cn = toChannelName(channel);
CompletableFuture<Codec> f = subscribeService.unsubscribe(cn, PubSubType.PUNSUBSCRIBE);
f = f.whenComplete((res, e) -> {
synchronized (RedissonReactiveSubscription.this.patterns) {
Collection<PubSubConnectionEntry> entries = RedissonReactiveSubscription.this.patterns.get(cn);
entries.stream()
.filter(en -> en.hasListeners(cn))
.forEach(ee -> RedissonReactiveSubscription.this.patterns.remove(cn));
RedissonReactiveSubscription.this.patterns.computeIfPresent(cn, (key, entries) -> {
entries.removeIf(entry -> !entry.hasListeners(cn));
if (entries.isEmpty()) {
return null;
}
return entries;
});
});
futures.add(f);
}

@ -36,6 +36,7 @@ import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
@ -48,20 +49,17 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
public static class ListenableCounter {
private int state;
private final AtomicInteger state = new AtomicInteger();
private Runnable r;
public synchronized void acquire() {
state++;
public void acquire() {
state.incrementAndGet();
}
public void release() {
synchronized (this) {
state--;
if (state != 0) {
if (state.decrementAndGet() != 0) {
return;
}
}
if (r != null) {
r.run();
@ -69,13 +67,11 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
}
}
public synchronized void addListener(Runnable r) {
synchronized (this) {
if (state != 0) {
public void addListener(Runnable r) {
if (state.get() != 0) {
this.r = r;
return;
}
}
r.run();
}
@ -175,17 +171,13 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
ChannelName cn = toChannelName(channel);
CompletableFuture<Codec> f = subscribeService.unsubscribe(cn, PubSubType.UNSUBSCRIBE);
f = f.whenComplete((res, e) -> {
synchronized (RedissonReactiveSubscription.this.channels) {
Collection<PubSubConnectionEntry> entries = RedissonReactiveSubscription.this.channels.get(cn);
for (PubSubConnectionEntry entry : entries) {
if (!entry.hasListeners(cn)) {
entries.remove(entry);
RedissonReactiveSubscription.this.channels.computeIfPresent(cn, (key, entries) -> {
entries.removeIf(entry -> !entry.hasListeners(cn));
if (entries.isEmpty()) {
RedissonReactiveSubscription.this.channels.remove(cn);
}
}
}
return null;
}
return entries;
});
});
futures.add(f);
}
@ -212,12 +204,13 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
ChannelName cn = toChannelName(channel);
CompletableFuture<Codec> f = subscribeService.unsubscribe(cn, PubSubType.PUNSUBSCRIBE);
f = f.whenComplete((res, e) -> {
synchronized (RedissonReactiveSubscription.this.patterns) {
Collection<PubSubConnectionEntry> entries = RedissonReactiveSubscription.this.patterns.get(cn);
entries.stream()
.filter(en -> en.hasListeners(cn))
.forEach(ee -> RedissonReactiveSubscription.this.patterns.remove(cn));
RedissonReactiveSubscription.this.patterns.computeIfPresent(cn, (key, entries) -> {
entries.removeIf(entry -> !entry.hasListeners(cn));
if (entries.isEmpty()) {
return null;
}
return entries;
});
});
futures.add(f);
}

@ -36,6 +36,7 @@ import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
@ -48,20 +49,17 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
public static class ListenableCounter {
private int state;
private final AtomicInteger state = new AtomicInteger();
private Runnable r;
public synchronized void acquire() {
state++;
public void acquire() {
state.incrementAndGet();
}
public void release() {
synchronized (this) {
state--;
if (state != 0) {
if (state.decrementAndGet() != 0) {
return;
}
}
if (r != null) {
r.run();
@ -69,13 +67,11 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
}
}
public synchronized void addListener(Runnable r) {
synchronized (this) {
if (state != 0) {
public void addListener(Runnable r) {
if (state.get() != 0) {
this.r = r;
return;
}
}
r.run();
}
@ -107,10 +103,6 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
}
}
@Override
public void onPatternMessage(CharSequence pattern, CharSequence channel, Object message) {
}
@Override
public void onMessage(CharSequence channel, Object msg) {
}
@ -175,17 +167,13 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
ChannelName cn = toChannelName(channel);
CompletableFuture<Codec> f = subscribeService.unsubscribe(cn, PubSubType.UNSUBSCRIBE);
f = f.whenComplete((res, e) -> {
synchronized (RedissonReactiveSubscription.this.channels) {
Collection<PubSubConnectionEntry> entries = RedissonReactiveSubscription.this.channels.get(cn);
for (PubSubConnectionEntry entry : entries) {
if (!entry.hasListeners(cn)) {
entries.remove(entry);
RedissonReactiveSubscription.this.channels.computeIfPresent(cn, (key, entries) -> {
entries.removeIf(entry -> !entry.hasListeners(cn));
if (entries.isEmpty()) {
RedissonReactiveSubscription.this.channels.remove(cn);
}
}
}
return null;
}
return entries;
});
});
futures.add(f);
}
@ -212,12 +200,13 @@ public class RedissonReactiveSubscription implements ReactiveSubscription {
ChannelName cn = toChannelName(channel);
CompletableFuture<Codec> f = subscribeService.unsubscribe(cn, PubSubType.PUNSUBSCRIBE);
f = f.whenComplete((res, e) -> {
synchronized (RedissonReactiveSubscription.this.patterns) {
Collection<PubSubConnectionEntry> entries = RedissonReactiveSubscription.this.patterns.get(cn);
entries.stream()
.filter(en -> en.hasListeners(cn))
.forEach(ee -> RedissonReactiveSubscription.this.patterns.remove(cn));
RedissonReactiveSubscription.this.patterns.computeIfPresent(cn, (key, entries) -> {
entries.removeIf(entry -> !entry.hasListeners(cn));
if (entries.isEmpty()) {
return null;
}
return entries;
});
});
futures.add(f);
}

Loading…
Cancel
Save