refactoring

pull/2041/head
Nikita Koksharov 6 years ago
parent b88765b8a6
commit 1f0459fef1

@ -31,6 +31,7 @@ import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.stream.Collectors;
import org.redisson.api.RBlockingQueue; import org.redisson.api.RBlockingQueue;
import org.redisson.api.RFuture; import org.redisson.api.RFuture;
@ -47,6 +48,7 @@ import org.redisson.client.protocol.RedisCommands;
import org.redisson.codec.CompositeCodec; import org.redisson.codec.CompositeCodec;
import org.redisson.command.CommandAsyncExecutor; import org.redisson.command.CommandAsyncExecutor;
import org.redisson.executor.RemotePromise; import org.redisson.executor.RemotePromise;
import org.redisson.misc.Hash;
import org.redisson.misc.RPromise; import org.redisson.misc.RPromise;
import org.redisson.misc.RedissonPromise; import org.redisson.misc.RedissonPromise;
import org.redisson.remote.RRemoteServiceResponse; import org.redisson.remote.RRemoteServiceResponse;
@ -64,6 +66,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.util.CharsetUtil;
import io.netty.util.Timeout; import io.netty.util.Timeout;
import io.netty.util.TimerTask; import io.netty.util.TimerTask;
import io.netty.util.concurrent.ScheduledFuture; import io.netty.util.concurrent.ScheduledFuture;
@ -78,7 +82,7 @@ public abstract class BaseRemoteService {
private static final Logger log = LoggerFactory.getLogger(BaseRemoteService.class); private static final Logger log = LoggerFactory.getLogger(BaseRemoteService.class);
private final Map<Class<?>, String> requestQueueNameCache = new ConcurrentHashMap<>(); private final Map<Class<?>, String> requestQueueNameCache = new ConcurrentHashMap<>();
private final ConcurrentMap<Method, List<String>> methodSignaturesCache = new ConcurrentHashMap<>(); private final ConcurrentMap<Method, long[]> methodSignaturesCache = new ConcurrentHashMap<>();
protected final Codec codec; protected final Codec codec;
protected final RedissonClient redisson; protected final RedissonClient redisson;
@ -200,7 +204,7 @@ public abstract class BaseRemoteService {
Long ackTimeout = optionsCopy.getAckTimeoutInMillis(); Long ackTimeout = optionsCopy.getAckTimeoutInMillis();
RemoteServiceRequest request = new RemoteServiceRequest(executorId, requestId.toString(), method.getName(), getMethodSignatures(method), args, RemoteServiceRequest request = new RemoteServiceRequest(executorId, requestId.toString(), method.getName(), getMethodSignature(method), args,
optionsCopy, System.currentTimeMillis()); optionsCopy, System.currentTimeMillis());
final RFuture<RemoteServiceAck> ackFuture; final RFuture<RemoteServiceAck> ackFuture;
@ -507,7 +511,7 @@ public abstract class BaseRemoteService {
RequestId requestId = generateRequestId(); RequestId requestId = generateRequestId();
String requestQueueName = getRequestQueueName(remoteInterface); String requestQueueName = getRequestQueueName(remoteInterface);
RemoteServiceRequest request = new RemoteServiceRequest(executorId, requestId.toString(), method.getName(), getMethodSignatures(method), args, optionsCopy, RemoteServiceRequest request = new RemoteServiceRequest(executorId, requestId.toString(), method.getName(), getMethodSignature(method), args, optionsCopy,
System.currentTimeMillis()); System.currentTimeMillis());
final RFuture<RemoteServiceAck> ackFuture; final RFuture<RemoteServiceAck> ackFuture;
@ -676,16 +680,19 @@ public abstract class BaseRemoteService {
} }
} }
protected List<String> getMethodSignatures(Method method) {
List<String> result = methodSignaturesCache.get(method); protected long[] getMethodSignature(Method method) {
long[] result = methodSignaturesCache.get(method);
if (result == null) { if (result == null) {
result = new ArrayList<>(method.getParameterTypes().length); String str = Arrays.stream(method.getParameterTypes())
for (Class<?> t : method.getParameterTypes()) { .map(c -> c.getName())
result.add(t.getName()); .collect(Collectors.joining());
} ByteBuf buf = Unpooled.copiedBuffer(str, CharsetUtil.UTF_8);
List<String> oldList = methodSignaturesCache.putIfAbsent(method, result); result = Hash.hash128(buf);
if (oldList != null) { buf.release();
result = oldList; long[] oldResult = methodSignaturesCache.putIfAbsent(method, result);
if (oldResult != null) {
return oldResult;
} }
} }

@ -125,7 +125,7 @@ public class RedissonRemoteService extends BaseRemoteService implements RRemoteS
@Override @Override
public <T> void deregister(Class<T> remoteInterface) { public <T> void deregister(Class<T> remoteInterface) {
for (Method method : remoteInterface.getMethods()) { for (Method method : remoteInterface.getMethods()) {
RemoteServiceKey key = new RemoteServiceKey(remoteInterface, method.getName(), getMethodSignatures(method)); RemoteServiceKey key = new RemoteServiceKey(remoteInterface, method.getName(), getMethodSignature(method));
beans.remove(key); beans.remove(key);
} }
@ -156,7 +156,7 @@ public class RedissonRemoteService extends BaseRemoteService implements RRemoteS
} }
for (Method method : remoteInterface.getMethods()) { for (Method method : remoteInterface.getMethods()) {
RemoteServiceMethod value = new RemoteServiceMethod(method, object); RemoteServiceMethod value = new RemoteServiceMethod(method, object);
RemoteServiceKey key = new RemoteServiceKey(remoteInterface, method.getName(), getMethodSignatures(method)); RemoteServiceKey key = new RemoteServiceKey(remoteInterface, method.getName(), getMethodSignature(method));
if (beans.put(key, value) != null) { if (beans.put(key, value) != null) {
return; return;
} }
@ -307,7 +307,7 @@ public class RedissonRemoteService extends BaseRemoteService implements RRemoteS
private <T> void executeMethod(Class<T> remoteInterface, RBlockingQueue<String> requestQueue, private <T> void executeMethod(Class<T> remoteInterface, RBlockingQueue<String> requestQueue,
ExecutorService executor, RemoteServiceRequest request) { ExecutorService executor, RemoteServiceRequest request) {
RemoteServiceMethod method = beans.get(new RemoteServiceKey(remoteInterface, request.getMethodName(), request.getSignatures())); RemoteServiceMethod method = beans.get(new RemoteServiceKey(remoteInterface, request.getMethodName(), request.getSignature()));
String responseName = getResponseQueueName(request.getExecutorId()); String responseName = getResponseQueueName(request.getExecutorId());

@ -62,7 +62,7 @@ public class PublishSubscribeService {
private final ConcurrentMap<ChannelName, PubSubConnectionEntry> name2PubSubConnection = new ConcurrentHashMap<>(); private final ConcurrentMap<ChannelName, PubSubConnectionEntry> name2PubSubConnection = new ConcurrentHashMap<>();
private final Queue<PubSubConnectionEntry> freePubSubConnections = new ConcurrentLinkedQueue<PubSubConnectionEntry>(); private final Queue<PubSubConnectionEntry> freePubSubConnections = new ConcurrentLinkedQueue<>();
private final SemaphorePubSub semaphorePubSub = new SemaphorePubSub(this); private final SemaphorePubSub semaphorePubSub = new SemaphorePubSub(this);
@ -109,9 +109,9 @@ public class PublishSubscribeService {
return subscribe(PubSubType.SUBSCRIBE, codec, channelName, new RedissonPromise<PubSubConnectionEntry>(), listeners); return subscribe(PubSubType.SUBSCRIBE, codec, channelName, new RedissonPromise<PubSubConnectionEntry>(), listeners);
} }
private RFuture<PubSubConnectionEntry> subscribe(final PubSubType type, final Codec codec, final ChannelName channelName, private RFuture<PubSubConnectionEntry> subscribe(PubSubType type, Codec codec, ChannelName channelName,
final RPromise<PubSubConnectionEntry> promise, final RedisPubSubListener<?>... listeners) { RPromise<PubSubConnectionEntry> promise, RedisPubSubListener<?>... listeners) {
final AsyncSemaphore lock = getSemaphore(channelName); AsyncSemaphore lock = getSemaphore(channelName);
lock.acquire(new Runnable() { lock.acquire(new Runnable() {
@Override @Override
public void run() { public void run() {
@ -120,7 +120,7 @@ public class PublishSubscribeService {
return; return;
} }
final RPromise<PubSubConnectionEntry> result = new RedissonPromise<PubSubConnectionEntry>(); RPromise<PubSubConnectionEntry> result = new RedissonPromise<PubSubConnectionEntry>();
promise.onComplete((res, e) -> { promise.onComplete((res, e) -> {
if (e != null) { if (e != null) {
result.tryFailure(e); result.tryFailure(e);
@ -150,11 +150,11 @@ public class PublishSubscribeService {
return locks[Math.abs(channelName.hashCode() % locks.length)]; return locks[Math.abs(channelName.hashCode() % locks.length)];
} }
private void subscribe(final Codec codec, final ChannelName channelName, private void subscribe(Codec codec, ChannelName channelName,
final RPromise<PubSubConnectionEntry> promise, final PubSubType type, final AsyncSemaphore lock, final RedisPubSubListener<?>... listeners) { RPromise<PubSubConnectionEntry> promise, PubSubType type, AsyncSemaphore lock, RedisPubSubListener<?>... listeners) {
final PubSubConnectionEntry connEntry = name2PubSubConnection.get(channelName); PubSubConnectionEntry connEntry = name2PubSubConnection.get(channelName);
if (connEntry != null) { if (connEntry != null) {
subscribe(channelName, promise, type, lock, connEntry, listeners); addListeners(channelName, promise, type, lock, connEntry, listeners);
return; return;
} }
@ -168,7 +168,7 @@ public class PublishSubscribeService {
return; return;
} }
final PubSubConnectionEntry freeEntry = freePubSubConnections.peek(); PubSubConnectionEntry freeEntry = freePubSubConnections.peek();
if (freeEntry == null) { if (freeEntry == null) {
connect(codec, channelName, promise, type, lock, listeners); connect(codec, channelName, promise, type, lock, listeners);
return; return;
@ -179,12 +179,12 @@ public class PublishSubscribeService {
throw new IllegalStateException(); throw new IllegalStateException();
} }
final PubSubConnectionEntry oldEntry = name2PubSubConnection.putIfAbsent(channelName, freeEntry); PubSubConnectionEntry oldEntry = name2PubSubConnection.putIfAbsent(channelName, freeEntry);
if (oldEntry != null) { if (oldEntry != null) {
freeEntry.release(); freeEntry.release();
freePubSubLock.release(); freePubSubLock.release();
subscribe(channelName, promise, type, lock, oldEntry, listeners); addListeners(channelName, promise, type, lock, oldEntry, listeners);
return; return;
} }
@ -193,7 +193,7 @@ public class PublishSubscribeService {
} }
freePubSubLock.release(); freePubSubLock.release();
subscribe(channelName, promise, type, lock, freeEntry, listeners); addListeners(channelName, promise, type, lock, freeEntry, listeners);
if (PubSubType.PSUBSCRIBE == type) { if (PubSubType.PSUBSCRIBE == type) {
freeEntry.psubscribe(codec, channelName); freeEntry.psubscribe(codec, channelName);
@ -205,14 +205,14 @@ public class PublishSubscribeService {
}); });
} }
private void subscribe(final ChannelName channelName, final RPromise<PubSubConnectionEntry> promise, private void addListeners(ChannelName channelName, RPromise<PubSubConnectionEntry> promise,
final PubSubType type, final AsyncSemaphore lock, final PubSubConnectionEntry connEntry, PubSubType type, AsyncSemaphore lock, PubSubConnectionEntry connEntry,
final RedisPubSubListener<?>... listeners) { RedisPubSubListener<?>... listeners) {
for (RedisPubSubListener<?> listener : listeners) { for (RedisPubSubListener<?> listener : listeners) {
connEntry.addListener(channelName, listener); connEntry.addListener(channelName, listener);
} }
SubscribeListener list = connEntry.getSubscribeFuture(channelName, type); SubscribeListener list = connEntry.getSubscribeFuture(channelName, type);
final RFuture<Void> subscribeFuture = list.getSuccessFuture(); RFuture<Void> subscribeFuture = list.getSuccessFuture();
subscribeFuture.onComplete((res, e) -> { subscribeFuture.onComplete((res, e) -> {
if (!promise.trySuccess(connEntry)) { if (!promise.trySuccess(connEntry)) {
@ -283,14 +283,14 @@ public class PublishSubscribeService {
freePubSubLock.release(); freePubSubLock.release();
subscribe(channelName, promise, type, lock, oldEntry, listeners); addListeners(channelName, promise, type, lock, oldEntry, listeners);
return; return;
} }
freePubSubConnections.add(entry); freePubSubConnections.add(entry);
freePubSubLock.release(); freePubSubLock.release();
subscribe(channelName, promise, type, lock, entry, listeners); addListeners(channelName, promise, type, lock, entry, listeners);
if (PubSubType.PSUBSCRIBE == type) { if (PubSubType.PSUBSCRIBE == type) {
entry.psubscribe(codec, channelName); entry.psubscribe(codec, channelName);
@ -300,14 +300,14 @@ public class PublishSubscribeService {
}); });
} }
public RFuture<Void> unsubscribe(final ChannelName channelName, final AsyncSemaphore lock) { public RFuture<Void> unsubscribe(ChannelName channelName, AsyncSemaphore lock) {
final PubSubConnectionEntry entry = name2PubSubConnection.remove(channelName); PubSubConnectionEntry entry = name2PubSubConnection.remove(channelName);
if (entry == null || connectionManager.isShuttingDown()) { if (entry == null || connectionManager.isShuttingDown()) {
lock.release(); lock.release();
return RedissonPromise.newSucceededFuture(null); return RedissonPromise.newSucceededFuture(null);
} }
final RedissonPromise<Void> result = new RedissonPromise<Void>(); RedissonPromise<Void> result = new RedissonPromise<Void>();
entry.unsubscribe(channelName, new BaseRedisPubSubListener() { entry.unsubscribe(channelName, new BaseRedisPubSubListener() {
@Override @Override
@ -329,17 +329,17 @@ public class PublishSubscribeService {
return result; return result;
} }
public RFuture<Codec> unsubscribe(final ChannelName channelName, final PubSubType topicType) { public RFuture<Codec> unsubscribe(ChannelName channelName, PubSubType topicType) {
if (connectionManager.isShuttingDown()) { if (connectionManager.isShuttingDown()) {
return RedissonPromise.newSucceededFuture(null); return RedissonPromise.newSucceededFuture(null);
} }
final RPromise<Codec> result = new RedissonPromise<Codec>(); RPromise<Codec> result = new RedissonPromise<>();
final AsyncSemaphore lock = getSemaphore(channelName); AsyncSemaphore lock = getSemaphore(channelName);
lock.acquire(new Runnable() { lock.acquire(new Runnable() {
@Override @Override
public void run() { public void run() {
final PubSubConnectionEntry entry = name2PubSubConnection.remove(channelName); PubSubConnectionEntry entry = name2PubSubConnection.remove(channelName);
if (entry == null) { if (entry == null) {
lock.release(); lock.release();
result.trySuccess(null); result.trySuccess(null);
@ -352,7 +352,7 @@ public class PublishSubscribeService {
freePubSubConnections.remove(entry); freePubSubConnections.remove(entry);
freePubSubLock.release(); freePubSubLock.release();
final Codec entryCodec; Codec entryCodec;
if (topicType == PubSubType.PUNSUBSCRIBE) { if (topicType == PubSubType.PUNSUBSCRIBE) {
entryCodec = entry.getConnection().getPatternChannels().get(channelName); entryCodec = entry.getConnection().getPatternChannels().get(channelName);
} else { } else {
@ -385,8 +385,8 @@ public class PublishSubscribeService {
return result; return result;
} }
public void punsubscribe(final ChannelName channelName, final AsyncSemaphore lock) { public void punsubscribe(ChannelName channelName, AsyncSemaphore lock) {
final PubSubConnectionEntry entry = name2PubSubConnection.remove(channelName); PubSubConnectionEntry entry = name2PubSubConnection.remove(channelName);
if (entry == null) { if (entry == null) {
lock.release(); lock.release();
return; return;
@ -444,8 +444,8 @@ public class PublishSubscribeService {
}); });
} }
private void subscribe(final ChannelName channelName, final Collection<RedisPubSubListener<?>> listeners, private void subscribe(ChannelName channelName, Collection<RedisPubSubListener<?>> listeners,
final Codec subscribeCodec) { Codec subscribeCodec) {
RFuture<PubSubConnectionEntry> subscribeFuture = subscribe(subscribeCodec, channelName, listeners.toArray(new RedisPubSubListener[listeners.size()])); RFuture<PubSubConnectionEntry> subscribeFuture = subscribe(subscribeCodec, channelName, listeners.toArray(new RedisPubSubListener[listeners.size()]));
subscribeFuture.onComplete((res, e) -> { subscribeFuture.onComplete((res, e) -> {
if (e != null) { if (e != null) {
@ -457,8 +457,8 @@ public class PublishSubscribeService {
}); });
} }
private void psubscribe(final ChannelName channelName, final Collection<RedisPubSubListener<?>> listeners, private void psubscribe(ChannelName channelName, Collection<RedisPubSubListener<?>> listeners,
final Codec subscribeCodec) { Codec subscribeCodec) {
RFuture<PubSubConnectionEntry> subscribeFuture = psubscribe(channelName, subscribeCodec, listeners.toArray(new RedisPubSubListener[listeners.size()])); RFuture<PubSubConnectionEntry> subscribeFuture = psubscribe(channelName, subscribeCodec, listeners.toArray(new RedisPubSubListener[listeners.size()]));
subscribeFuture.onComplete((res, e) -> { subscribeFuture.onComplete((res, e) -> {
if (e != null) { if (e != null) {

@ -15,8 +15,7 @@
*/ */
package org.redisson.remote; package org.redisson.remote;
import java.util.Collections; import java.util.Arrays;
import java.util.List;
/** /**
* *
@ -27,21 +26,21 @@ public class RemoteServiceKey {
private final Class<?> serviceInterface; private final Class<?> serviceInterface;
private final String methodName; private final String methodName;
private final List<String> signatures; private final long[] signature;
public RemoteServiceKey(Class<?> serviceInterface, String method, List<String> signatures) { public RemoteServiceKey(Class<?> serviceInterface, String method, long[] signature) {
super(); super();
this.serviceInterface = serviceInterface; this.serviceInterface = serviceInterface;
this.methodName = method; this.methodName = method;
this.signatures = Collections.unmodifiableList(signatures); this.signature = signature;
} }
public String getMethodName() { public String getMethodName() {
return methodName; return methodName;
} }
public List<String> getSignatures() { public long[] getSignature() {
return signatures; return signature;
} }
public Class<?> getServiceInterface() { public Class<?> getServiceInterface() {
@ -54,8 +53,8 @@ public class RemoteServiceKey {
final int prime = 31; final int prime = 31;
int result = 1; int result = 1;
result = prime * result + ((methodName == null) ? 0 : methodName.hashCode()); result = prime * result + ((methodName == null) ? 0 : methodName.hashCode());
result = prime * result + ((signatures == null) ? 0 : signatures.hashCode());
result = prime * result + ((serviceInterface == null) ? 0 : serviceInterface.getName().hashCode()); result = prime * result + ((serviceInterface == null) ? 0 : serviceInterface.getName().hashCode());
result = prime * result + Arrays.hashCode(signature);
return result; return result;
} }
@ -71,15 +70,15 @@ public class RemoteServiceKey {
if (methodName == null) { if (methodName == null) {
if (other.methodName != null) if (other.methodName != null)
return false; return false;
} else if (!methodName.equals(other.methodName)) { } else if (!methodName.equals(other.methodName))
return false; return false;
} else if (!signatures.equals(other.signatures)) { if (serviceInterface == null) {
return false;
} else if (serviceInterface == null) {
if (other.serviceInterface != null) if (other.serviceInterface != null)
return false; return false;
} else if (!serviceInterface.equals(other.serviceInterface)) } else if (!serviceInterface.equals(other.serviceInterface))
return false; return false;
if (!Arrays.equals(signature, other.signature))
return false;
return true; return true;
} }

@ -17,7 +17,6 @@ package org.redisson.remote;
import java.io.Serializable; import java.io.Serializable;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
import org.redisson.api.RemoteInvocationOptions; import org.redisson.api.RemoteInvocationOptions;
@ -33,7 +32,7 @@ public class RemoteServiceRequest implements Serializable {
private String id; private String id;
private String executorId; private String executorId;
private String methodName; private String methodName;
private List<String> signatures; private long[] signature;
private Object[] args; private Object[] args;
private RemoteInvocationOptions options; private RemoteInvocationOptions options;
private long date; private long date;
@ -46,12 +45,12 @@ public class RemoteServiceRequest implements Serializable {
this.id = id; this.id = id;
} }
public RemoteServiceRequest(String executorId, String id, String methodName, List<String> signatures, Object[] args, RemoteInvocationOptions options, long date) { public RemoteServiceRequest(String executorId, String id, String methodName, long[] signature, Object[] args, RemoteInvocationOptions options, long date) {
super(); super();
this.id = id; this.id = id;
this.executorId = executorId; this.executorId = executorId;
this.methodName = methodName; this.methodName = methodName;
this.signatures = signatures; this.signature = signature;
this.args = args; this.args = args;
this.options = options; this.options = options;
this.date = date; this.date = date;
@ -73,8 +72,8 @@ public class RemoteServiceRequest implements Serializable {
return args; return args;
} }
public List<String> getSignatures() { public long[] getSignature() {
return signatures; return signature;
} }
public RemoteInvocationOptions getOptions() { public RemoteInvocationOptions getOptions() {
@ -87,8 +86,8 @@ public class RemoteServiceRequest implements Serializable {
@Override @Override
public String toString() { public String toString() {
return "RemoteServiceRequest [requestId=" + id + ", methodName=" + methodName + ", signatures=[" return "RemoteServiceRequest [requestId=" + id + ", methodName=" + methodName + ", signature="
+ Arrays.toString(signatures.toArray()) + "], args=" + signature + ", args="
+ Arrays.toString(args) + ", options=" + options + ", date=" + date + "]"; + Arrays.toString(args) + ", options=" + options + ", date=" + date + "]";
} }

Loading…
Cancel
Save