use of org.redisson.client.codec.Codec in project redisson by redisson.
the class PublishSubscribeService method subscribe.
private void subscribe(Codec codec, ChannelName channelName, MasterSlaveEntry entry, CompletableFuture<PubSubConnectionEntry> promise, PubSubType type, AsyncSemaphore lock, AtomicInteger attempts, RedisPubSubListener<?>... listeners) {
PubSubConnectionEntry connEntry = name2PubSubConnection.get(new PubSubKey(channelName, entry));
if (connEntry != null) {
addListeners(channelName, promise, type, lock, connEntry, listeners);
return;
}
Timeout lockTimeout = connectionManager.newTimeout(timeout -> {
promise.completeExceptionally(new RedisTimeoutException("Unable to acquire subscription lock after " + config.getTimeout() + "ms. " + "Increase 'subscriptionsPerConnection' and/or 'subscriptionConnectionPoolSize' parameters."));
}, config.getTimeout(), TimeUnit.MILLISECONDS);
freePubSubLock.acquire(() -> {
if (!lockTimeout.cancel() || promise.isDone()) {
lock.release();
freePubSubLock.release();
return;
}
MasterSlaveEntry msEntry = Optional.ofNullable(connectionManager.getEntry(entry.getClient())).orElse(entry);
PubSubEntry freePubSubConnections = entry2PubSubConnection.getOrDefault(msEntry, new PubSubEntry());
PubSubConnectionEntry freeEntry = freePubSubConnections.getEntries().peek();
if (freeEntry == null) {
freePubSubLock.release();
CompletableFuture<RedisPubSubConnection> connectFuture = connect(codec, channelName, msEntry, promise, type, lock, listeners);
connectionManager.newTimeout(t -> {
if (attempts.get() == config.getRetryAttempts()) {
connectFuture.completeExceptionally(new RedisTimeoutException("Unable to acquire connection for subscription after " + attempts.get() + " attempts. " + "Increase 'subscriptionsPerConnection' and/or 'subscriptionConnectionPoolSize' parameters."));
return;
}
if (connectFuture.cancel(true)) {
subscribe(codec, channelName, entry, promise, type, lock, attempts, listeners);
attempts.incrementAndGet();
}
}, config.getRetryInterval(), TimeUnit.MILLISECONDS);
return;
}
int remainFreeAmount = freeEntry.tryAcquire();
if (remainFreeAmount == -1) {
throw new IllegalStateException();
}
PubSubKey key = new PubSubKey(channelName, msEntry);
PubSubConnectionEntry oldEntry = name2PubSubConnection.putIfAbsent(key, freeEntry);
if (oldEntry != null) {
freeEntry.release();
freePubSubLock.release();
addListeners(channelName, promise, type, lock, oldEntry, listeners);
return;
}
if (remainFreeAmount == 0) {
freePubSubConnections.getEntries().poll();
}
freePubSubLock.release();
CompletableFuture<Void> subscribeFuture = addListeners(channelName, promise, type, lock, freeEntry, listeners);
ChannelFuture future;
if (PubSubType.PSUBSCRIBE == type) {
future = freeEntry.psubscribe(codec, channelName);
} else {
future = freeEntry.subscribe(codec, channelName);
}
future.addListener((ChannelFutureListener) future1 -> {
if (!future1.isSuccess()) {
if (!promise.isDone()) {
subscribeFuture.cancel(false);
}
return;
}
connectionManager.newTimeout(timeout -> {
if (subscribeFuture.completeExceptionally(new RedisTimeoutException("Subscription timeout after " + config.getTimeout() + "ms. " + "Check network and/or increase 'timeout' parameter."))) {
unsubscribe(channelName, type);
}
}, config.getTimeout(), TimeUnit.MILLISECONDS);
});
});
}
use of org.redisson.client.codec.Codec in project redisson by redisson.
the class CollectionMapperTask method run.
@Override
public void run() {
Codec codec;
try {
codec = (Codec) objectCodecClass.getConstructor().newInstance();
} catch (Exception e) {
throw new IllegalStateException(e);
}
Injector.inject(mapper, redisson);
for (String objectName : objectNames) {
Iterable<VIn> collection = null;
if (RSetCache.class.isAssignableFrom(objectClass)) {
collection = redisson.getSetCache(objectName, codec);
} else if (RSet.class.isAssignableFrom(objectClass)) {
collection = redisson.getSet(objectName, codec);
} else if (RSortedSet.class.isAssignableFrom(objectClass)) {
collection = redisson.getSortedSet(objectName, codec);
} else if (RScoredSortedSet.class.isAssignableFrom(objectClass)) {
collection = redisson.getScoredSortedSet(objectName, codec);
} else if (RLexSortedSet.class.isAssignableFrom(objectClass)) {
collection = (Iterable<VIn>) redisson.getLexSortedSet(objectName);
} else if (RList.class.isAssignableFrom(objectClass)) {
collection = redisson.getList(objectName, codec);
} else {
throw new IllegalStateException("Unable to work with " + objectClass);
}
RCollector<KOut, VOut> collector = new Collector<KOut, VOut>(codec, redisson, collectorMapName, workersAmount, timeout);
for (VIn value : collection) {
if (Thread.currentThread().isInterrupted()) {
return;
}
mapper.map(value, collector);
}
}
}
use of org.redisson.client.codec.Codec in project redisson by redisson.
the class MapperTask method run.
@Override
public void run() {
Codec codec;
try {
codec = (Codec) objectCodecClass.getConstructor().newInstance();
} catch (Exception e) {
throw new IllegalStateException(e);
}
Injector.inject(mapper, redisson);
RCollector<KOut, VOut> collector = new Collector<KOut, VOut>(codec, redisson, collectorMapName, workersAmount, timeout);
for (String objectName : objectNames) {
RMap<KIn, VIn> map = null;
if (RMapCache.class.isAssignableFrom(objectClass)) {
map = redisson.getMapCache(objectName, codec);
} else {
map = redisson.getMap(objectName, codec);
}
for (Entry<KIn, VIn> entry : map.entrySet()) {
if (Thread.currentThread().isInterrupted()) {
return;
}
mapper.map(entry.getKey(), entry.getValue(), collector);
}
}
}
use of org.redisson.client.codec.Codec in project redisson by redisson.
the class RedissonReactiveSubscription method unsubscribe.
@Override
public Mono<Void> unsubscribe(ByteBuffer... channels) {
monosListener.acquire();
return Mono.defer(() -> {
List<CompletableFuture<?>> futures = new ArrayList<>(channels.length);
for (ByteBuffer channel : channels) {
ChannelName cn = toChannelName(channel);
CompletableFuture<Codec> f = subscribeService.unsubscribe(cn, PubSubType.UNSUBSCRIBE);
f = f.whenComplete((res, e) -> {
synchronized (RedissonReactiveSubscription.this.channels) {
PubSubConnectionEntry entry = RedissonReactiveSubscription.this.channels.get(cn);
if (!entry.hasListeners(cn)) {
RedissonReactiveSubscription.this.channels.remove(cn);
}
}
});
futures.add(f);
}
CompletableFuture<Void> future = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
future = future.whenComplete((r, e) -> {
monosListener.release();
});
return Mono.fromFuture(future);
});
}
use of org.redisson.client.codec.Codec in project redisson by redisson.
the class MasterSlaveConnectionManager method punsubscribe.
public Codec punsubscribe(final String channelName, final AsyncSemaphore lock) {
final PubSubConnectionEntry entry = name2PubSubConnection.remove(channelName);
if (entry == null) {
lock.release();
return null;
}
Codec entryCodec = entry.getConnection().getPatternChannels().get(channelName);
entry.punsubscribe(channelName, new BaseRedisPubSubListener() {
@Override
public boolean onStatus(PubSubType type, String channel) {
if (type == PubSubType.PUNSUBSCRIBE && channel.equals(channelName)) {
if (entry.release() == 1) {
freePubSubConnections.add(entry);
}
lock.release();
return true;
}
return false;
}
});
return entryCodec;
}
Aggregations