Merge branch 'master' into 3.0.0

pull/1821/head
Nikita 7 years ago
commit d5b68f4289

@ -60,6 +60,7 @@
<module>redisson-all</module>
<module>redisson-tomcat</module>
<module>redisson-spring-data</module>
<module>redisson-spring-boot-starter</module>
</modules>
<profiles>
@ -135,7 +136,7 @@
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-bom</artifactId>
<version>4.1.28.Final</version>
<version>4.1.29.Final</version>
<type>pom</type>
<scope>import</scope>
</dependency>

@ -194,7 +194,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<version>3.1.1</version>
<executions>
<execution>
<id>shade-artifacts</id>
@ -212,21 +212,19 @@
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
<configuration>
<includeDependencySources>true</includeDependencySources>
<dependencySourceIncludes>
<dependencySourceInclude>org.redisson:*</dependencySourceInclude>
<dependencySourceInclude>org.redisson:*,org.springframework.transaction:*</dependencySourceInclude>
</dependencySourceIncludes>
</configuration>
</plugin>

@ -0,0 +1,46 @@
Spring Boot Starter
===
Integrates Redisson with Spring Boot library.
Supports Spring Boot 1.3.x, 1.4.x, 1.5.x, 2.0.x
Usage
===
### 1. Add `redisson-spring-boot-starter` dependency into your project:
1. __For JDK 1.8+__
Maven
```xml
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.8.0</version>
</dependency>
```
Gradle
```java
compile 'org.redisson:redisson-spring-boot-starter:3.8.0'
```
2. __For JDK 1.6+__
Maven
```xml
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>2.13.0</version>
</dependency>
```
Gradle
```java
compile 'org.redisson:redisson-spring-boot-starter:2.13.0'
```
### 2. Get access to Redisson through spring bean with `RedissonClient` interface

@ -0,0 +1,129 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.redisson</groupId>
<artifactId>redisson-parent</artifactId>
<version>2.12.6-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<properties>
<spring-boot.version>1.5.15.RELEASE</spring-boot.version>
</properties>
<artifactId>redisson-spring-boot-starter</artifactId>
<packaging>jar</packaging>
<name>Redisson/Spring Boot Starter</name>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.mycila</groupId>
<artifactId>license-maven-plugin</artifactId>
<version>3.0</version>
<configuration>
<basedir>${basedir}</basedir>
<header>${basedir}/../header.txt</header>
<quiet>false</quiet>
<failIfMissing>true</failIfMissing>
<aggregate>false</aggregate>
<includes>
<include>src/main/java/org/redisson/</include>
</includes>
<excludes>
<exclude>target/**</exclude>
</excludes>
<useDefaultExcludes>true</useDefaultExcludes>
<mapping>
<java>JAVADOC_STYLE</java>
</mapping>
<strictCheck>true</strictCheck>
<useDefaultMapping>true</useDefaultMapping>
<encoding>UTF-8</encoding>
</configuration>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
</dependency>
-->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-data-18</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.10.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

@ -0,0 +1,149 @@
/**
* Copyright 2018 Nikita Koksharov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.redisson.spring.starter;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.List;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.spring.data.connection.RedissonConnectionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties.Sentinel;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.util.ReflectionUtils;
/**
*
* @author Nikita Koksharov
*
*/
@Configuration
@ConditionalOnClass(Redisson.class)
@AutoConfigureAfter(RedisAutoConfiguration.class)
@EnableConfigurationProperties(RedissonProperties.class)
public class RedissonAutoConfiguration {
@Autowired
private RedissonProperties redissonProperties;
@Autowired
private RedisProperties redisProperties;
@Autowired
private ApplicationContext ctx;
@Bean
@ConditionalOnMissingBean(RedisConnectionFactory.class)
public RedissonConnectionFactory redissonConnectionFactory(RedissonClient redisson) {
return new RedissonConnectionFactory(redisson);
}
@Bean(destroyMethod = "shutdown")
@ConditionalOnMissingBean(RedissonClient.class)
public RedissonClient redisson() throws IOException {
Config config = null;
Method clusterMethod = ReflectionUtils.findMethod(RedisProperties.class, "getCluster");
Method timeoutMethod = ReflectionUtils.findMethod(RedisProperties.class, "getTimeout");
Object timeoutValue = ReflectionUtils.invokeMethod(timeoutMethod, redisProperties);
int timeout;
if (!(timeoutValue instanceof Integer)) {
Method millisMethod = ReflectionUtils.findMethod(timeoutValue.getClass(), "toMillis");
timeout = ((Long) ReflectionUtils.invokeMethod(millisMethod, timeoutValue)).intValue();
} else {
timeout = (Integer)timeoutValue;
}
if (redissonProperties.getConfig() != null) {
try {
InputStream is = getConfigStream();
config = Config.fromJSON(is);
} catch (IOException e) {
// trying next format
try {
InputStream is = getConfigStream();
config = Config.fromYAML(is);
} catch (IOException e1) {
throw new IllegalArgumentException("Can't parse config", e1);
}
}
} else if (redisProperties.getSentinel() != null) {
Method nodesMethod = ReflectionUtils.findMethod(Sentinel.class, "getNodes");
Object nodesValue = ReflectionUtils.invokeMethod(nodesMethod, redisProperties.getSentinel());
String[] nodes;
if (nodesValue instanceof String) {
nodes = ((String)nodesValue).split(",");
} else {
nodes = ((List<String>)nodesValue).toArray(new String[((List<String>)nodesValue).size()]);
}
config = new Config();
config.useSentinelServers()
.setMasterName(redisProperties.getSentinel().getMaster())
.addSentinelAddress(nodes)
.setDatabase(redisProperties.getDatabase())
.setConnectTimeout(timeout)
.setPassword(redisProperties.getPassword());
} else if (clusterMethod != null && ReflectionUtils.invokeMethod(clusterMethod, redisProperties) != null) {
Object clusterObject = ReflectionUtils.invokeMethod(clusterMethod, redisProperties);
Method nodesMethod = ReflectionUtils.findMethod(clusterObject.getClass(), "getNodes");
List<String> nodesObject = (List) ReflectionUtils.invokeMethod(nodesMethod, clusterObject);
config = new Config();
config.useClusterServers()
.addNodeAddress(nodesObject.toArray(new String[nodesObject.size()]))
.setConnectTimeout(timeout)
.setPassword(redisProperties.getPassword());
} else {
config = new Config();
String prefix = "redis://";
Method method = ReflectionUtils.findMethod(RedisProperties.class, "isSsl");
if (method != null && (Boolean)ReflectionUtils.invokeMethod(method, redisProperties)) {
prefix = "rediss://";
}
config.useSingleServer()
.setAddress(prefix + redisProperties.getHost() + ":" + redisProperties.getPort())
.setConnectTimeout(timeout)
.setDatabase(redisProperties.getDatabase())
.setPassword(redisProperties.getPassword());
}
return Redisson.create(config);
}
protected InputStream getConfigStream() throws IOException {
Resource resource = ctx.getResource(redissonProperties.getConfig());
InputStream is = resource.getInputStream();
return is;
}
}

@ -0,0 +1,38 @@
/**
* Copyright 2018 Nikita Koksharov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.redisson.spring.starter;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
*
* @author Nikita Koksharov
*
*/
@ConfigurationProperties(prefix = "spring.redis.redisson")
public class RedissonProperties {
private String config;
public String getConfig() {
return config;
}
public void setConfig(String config) {
this.config = config;
}
}

@ -0,0 +1,15 @@
package org.redisson.spring.starter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
@EnableCaching
public class RedissonApplication {
public static void main(String[] args) {
SpringApplication.run(RedissonApplication.class, args);
}
}

@ -0,0 +1,43 @@
package org.redisson.spring.starter;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.redisson.client.codec.StringCodec;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(
classes = RedissonApplication.class,
properties = {
"spring.redis.redisson.config=classpath:redisson.yaml",
"spring.redis.timeout=10000"
})
public class RedissonAutoConfigurationTest {
@Autowired
private RedissonClient redisson;
@Autowired
private RedisTemplate<String, String> template;
@Test
public void testApp() {
redisson.getKeys().flushall();
RMap<String, String> m = redisson.getMap("test", StringCodec.INSTANCE);
m.put("1", "2");
BoundHashOperations<String, String, String> hash = template.boundHashOps("test");
String t = hash.get("1");
assertThat(t).isEqualTo("2");
}
}

@ -0,0 +1,31 @@
package org.redisson.spring.starter;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(
classes = RedissonApplication.class,
properties = {
"spring.redis.redisson.config=classpath:redisson.yaml",
"spring.redis.timeout=10000",
"spring.cache.type=redis",
})
public class RedissonCacheManagerAutoConfigurationTest {
@Autowired
private CacheManager cacheManager;
@Test
public void testApp() {
Cache cache = cacheManager.getCache("test");
Assert.assertNotNull(cache);
}
}

@ -0,0 +1,2 @@
singleServerConfig:
address: "redis://127.0.0.1:6379"

@ -31,13 +31,13 @@ Usage
```java
// for Spring Data Redis v.1.6.x
compile 'org.redisson:redisson-spring-data-16:3.8.0.RELEASE'
compile 'org.redisson:redisson-spring-data-16:3.8.0'
// for Spring Data Redis v.1.7.x
compile 'org.redisson:redisson-spring-data-17:3.8.0.RELEASE'
compile 'org.redisson:redisson-spring-data-17:3.8.0'
// for Spring Data Redis v.1.8.x
compile 'org.redisson:redisson-spring-data-18:3.8.0.RELEASE'
compile 'org.redisson:redisson-spring-data-18:3.8.0'
// for Spring Data Redis v.2.0.x
compile 'org.redisson:redisson-spring-data-20:3.8.0.RELEASE'
compile 'org.redisson:redisson-spring-data-20:3.8.0'
```
2. __For JDK 1.6+__
@ -61,13 +61,13 @@ Usage
```java
// for Spring Data Redis v.1.6.x
compile 'org.redisson:redisson-spring-data-16:2.13.0.RELEASE'
compile 'org.redisson:redisson-spring-data-16:2.13.0'
// for Spring Data Redis v.1.7.x
compile 'org.redisson:redisson-spring-data-17:2.13.0.RELEASE'
compile 'org.redisson:redisson-spring-data-17:2.13.0'
// for Spring Data Redis v.1.8.x
compile 'org.redisson:redisson-spring-data-18:2.13.0.RELEASE'
compile 'org.redisson:redisson-spring-data-18:2.13.0'
// for Spring Data Redis v.2.0.x
compile 'org.redisson:redisson-spring-data-20:2.13.0.RELEASE'
compile 'org.redisson:redisson-spring-data-20:2.13.0'
```

@ -29,7 +29,7 @@ Usage
* `AFTER_REQUEST` - all session attributes are stored into Redis after each request.
<br/>
`sharedSession` - share session across multiple deployed applications. Appropriate for migration EAR based application with multiple WARs. Works only in `readMode=REDIS`.
`sharedSession` - share session across multiple deployed applications. Appropriate solution for migration of EAR based application with multiple WARs hosted previously on JBoss, WebLogic... Works only in `readMode=REDIS`.
<i>This option available only in [Redisson PRO](http://redisson.pro) edition.</i>
* `false` - don't share single session. Default mode.

@ -22,7 +22,6 @@ import org.redisson.api.RFuture;
import org.redisson.api.RTopic;
import org.redisson.api.listener.BaseStatusListener;
import org.redisson.api.listener.MessageListener;
import org.redisson.client.ChannelName;
import org.redisson.connection.ConnectionManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -107,7 +106,7 @@ public abstract class QueueTransferTask {
private void scheduleTask(final Long startTime) {
TimeoutTask oldTimeout = lastTimeout.get();
if (startTime == null || (oldTimeout != null && oldTimeout.getStartTime() < startTime)) {
if (startTime == null) {
return;
}

@ -148,7 +148,7 @@ public class RedissonBucket<V> extends RedissonExpirable implements RBucket<V> {
@Override
public RFuture<Void> setAsync(V value, long timeToLive, TimeUnit timeUnit) {
if (value == null) {
throw new IllegalArgumentException("Value can't be null");
return commandExecutor.writeAsync(getName(), RedisCommands.DEL_VOID, getName());
}
return commandExecutor.writeAsync(getName(), codec, RedisCommands.PSETEX, getName(), timeUnit.toMillis(timeToLive), encode(value));

@ -430,7 +430,7 @@ public class RedissonExecutorService implements RScheduledExecutorService {
public RFuture<Boolean> deleteAsync() {
final RPromise<Boolean> result = new RedissonPromise<Boolean>();
RFuture<Long> deleteFuture = redisson.getKeys().deleteAsync(
requestQueueName, statusName, tasksCounterName, schedulerQueueName, tasksName);
requestQueueName, statusName, tasksCounterName, schedulerQueueName, tasksName, tasksRetryIntervalName);
deleteFuture.addListener(new FutureListener<Long>() {
@Override
public void operationComplete(io.netty.util.concurrent.Future<Long> future) throws Exception {

@ -36,7 +36,6 @@ import org.redisson.api.map.event.EntryExpiredListener;
import org.redisson.api.map.event.EntryRemovedListener;
import org.redisson.api.map.event.EntryUpdatedListener;
import org.redisson.api.map.event.MapEntryListener;
import org.redisson.client.ChannelName;
import org.redisson.client.RedisClient;
import org.redisson.client.codec.Codec;
import org.redisson.client.codec.LongCodec;
@ -82,12 +81,15 @@ import io.netty.util.concurrent.FutureListener;
*/
public class RedissonMapCache<K, V> extends RedissonMap<K, V> implements RMapCache<K, V> {
private EvictionScheduler evictionScheduler;
public RedissonMapCache(EvictionScheduler evictionScheduler, CommandAsyncExecutor commandExecutor,
String name, RedissonClient redisson, MapOptions<K, V> options) {
super(commandExecutor, name, redisson, options);
if (evictionScheduler != null) {
evictionScheduler.schedule(getName(), getTimeoutSetName(), getIdleSetName(), getExpiredChannelName(), getLastAccessTimeSetName());
}
this.evictionScheduler = evictionScheduler;
}
public RedissonMapCache(Codec codec, EvictionScheduler evictionScheduler, CommandAsyncExecutor commandExecutor,
@ -96,6 +98,7 @@ public class RedissonMapCache<K, V> extends RedissonMap<K, V> implements RMapCac
if (evictionScheduler != null) {
evictionScheduler.schedule(getName(), getTimeoutSetName(), getIdleSetName(), getExpiredChannelName(), getLastAccessTimeSetName());
}
this.evictionScheduler = evictionScheduler;
}
@Override
@ -2027,4 +2030,11 @@ public class RedissonMapCache<K, V> extends RedissonMap<K, V> implements RMapCac
Arrays.<Object>asList(getName(), getTimeoutSetName(), getIdleSetName(), getLastAccessTimeSetName(), getOptionsName()),
System.currentTimeMillis());
}
@Override
public void destroy() {
if (evictionScheduler != null) {
evictionScheduler.remove(getName());
}
}
}

@ -62,12 +62,14 @@ import io.netty.buffer.ByteBuf;
public class RedissonSetCache<V> extends RedissonExpirable implements RSetCache<V>, ScanIterator {
RedissonClient redisson;
EvictionScheduler evictionScheduler;
public RedissonSetCache(EvictionScheduler evictionScheduler, CommandAsyncExecutor commandExecutor, String name, RedissonClient redisson) {
super(commandExecutor, name);
if (evictionScheduler != null) {
evictionScheduler.schedule(getName(), 0);
}
this.evictionScheduler = evictionScheduler;
this.redisson = redisson;
}
@ -76,6 +78,7 @@ public class RedissonSetCache<V> extends RedissonExpirable implements RSetCache<
if (evictionScheduler != null) {
evictionScheduler.schedule(getName(), 0);
}
this.evictionScheduler = evictionScheduler;
this.redisson = redisson;
}
@ -378,4 +381,11 @@ public class RedissonSetCache<V> extends RedissonExpirable implements RSetCache<
return new RedissonLock(commandExecutor, lockName);
}
@Override
public void destroy() {
if (evictionScheduler != null) {
evictionScheduler.remove(getName());
}
}
}

@ -37,7 +37,7 @@ import org.redisson.api.map.event.MapEntryListener;
* @param <K> key
* @param <V> value
*/
public interface RMapCache<K, V> extends RMap<K, V>, RMapCacheAsync<K, V> {
public interface RMapCache<K, V> extends RMap<K, V>, RMapCacheAsync<K, V>, RDestroyable {
/**
* Sets max size of the map.

@ -38,7 +38,7 @@ import org.redisson.api.mapreduce.RCollectionMapReduce;
*
* @param <V> value
*/
public interface RSetCache<V> extends Set<V>, RExpirable, RSetCacheAsync<V> {
public interface RSetCache<V> extends Set<V>, RExpirable, RSetCacheAsync<V>, RDestroyable {
/**
* Returns lock instance associated with <code>value</code>

@ -62,7 +62,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.netty.resolver.AddressResolver;
import io.netty.util.CharsetUtil;
import io.netty.util.NetUtil;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.FutureListener;
@ -234,11 +233,11 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager {
final MasterSlaveEntry e;
List<RFuture<Void>> futures = new ArrayList<RFuture<Void>>();
if (config.checkSkipSlavesInit()) {
e = new SingleEntry(partition.getSlotRanges(), ClusterConnectionManager.this, config);
e = new SingleEntry(ClusterConnectionManager.this, config);
} else {
config.setSlaveAddresses(partition.getSlaveAddresses());
e = new MasterSlaveEntry(partition.getSlotRanges(), ClusterConnectionManager.this, config);
e = new MasterSlaveEntry(ClusterConnectionManager.this, config);
List<RFuture<Void>> fs = e.initSlaveBalancer(partition.getFailedSlaveAddresses());
futures.addAll(fs);
@ -596,7 +595,7 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager {
for (Integer slot : removedSlots) {
MasterSlaveEntry entry = removeEntry(slot);
if (entry.getSlotRanges().isEmpty()) {
if (entry.getReferences() == 0) {
entry.shutdownAsync();
log.info("{} master and slaves for it removed", entry.getClient().getAddr());
}
@ -633,9 +632,7 @@ public class ClusterConnectionManager extends MasterSlaveConnectionManager {
private void checkSlotsMigration(Collection<ClusterPartition> newPartitions) {
for (ClusterPartition currentPartition : getLastPartitions()) {
for (ClusterPartition newPartition : newPartitions) {
if (!currentPartition.getNodeId().equals(newPartition.getNodeId())
// skip master change case
|| !currentPartition.getMasterAddress().equals(newPartition.getMasterAddress())) {
if (!currentPartition.getNodeId().equals(newPartition.getNodeId())) {
continue;
}

@ -15,13 +15,11 @@
*/
package org.redisson.connection;
import java.lang.reflect.Field;
import java.net.InetSocketAddress;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@ -315,16 +313,7 @@ public class MasterSlaveConnectionManager implements ConnectionManager {
minTimeout = 100;
}
timer = new HashedWheelTimer(Executors.defaultThreadFactory(), minTimeout, TimeUnit.MILLISECONDS, 1024);
// to avoid assertion error during timer.stop invocation
try {
Field leakField = HashedWheelTimer.class.getDeclaredField("leak");
leakField.setAccessible(true);
leakField.set(timer, null);
} catch (Exception e) {
throw new IllegalStateException(e);
}
timer = new HashedWheelTimer(Executors.defaultThreadFactory(), minTimeout, TimeUnit.MILLISECONDS, 1024, false);
connectionWatcher = new IdleConnectionWatcher(this, config);
subscribeService = new PublishSubscribeService(this, config);
@ -332,14 +321,11 @@ public class MasterSlaveConnectionManager implements ConnectionManager {
protected void initSingleEntry() {
try {
HashSet<ClusterSlotRange> slots = new HashSet<ClusterSlotRange>();
slots.add(singleSlotRange);
MasterSlaveEntry entry;
if (config.checkSkipSlavesInit()) {
entry = new SingleEntry(slots, this, config);
entry = new SingleEntry(this, config);
} else {
entry = createMasterSlaveEntry(config, slots);
entry = createMasterSlaveEntry(config);
}
RFuture<RedisClient> f = entry.setupMasterEntry(config.getMasterAddress());
f.syncUninterruptibly();
@ -363,9 +349,8 @@ public class MasterSlaveConnectionManager implements ConnectionManager {
}
}
protected MasterSlaveEntry createMasterSlaveEntry(MasterSlaveServersConfig config,
HashSet<ClusterSlotRange> slots) {
MasterSlaveEntry entry = new MasterSlaveEntry(slots, this, config);
protected MasterSlaveEntry createMasterSlaveEntry(MasterSlaveServersConfig config) {
MasterSlaveEntry entry = new MasterSlaveEntry(this, config);
List<RFuture<Void>> fs = entry.initSlaveBalancer(java.util.Collections.<URI>emptySet());
for (RFuture<Void> future : fs) {
future.syncUninterruptibly();
@ -412,13 +397,13 @@ public class MasterSlaveConnectionManager implements ConnectionManager {
@Override
public RedisClient createClient(NodeType type, URI address, String sslHostname) {
RedisClient client = createClient(type, address, config.getConnectTimeout(), config.getRetryInterval() * config.getRetryAttempts(), sslHostname);
RedisClient client = createClient(type, address, config.getConnectTimeout(), config.getTimeout(), sslHostname);
return client;
}
@Override
public RedisClient createClient(NodeType type, InetSocketAddress address, URI uri, String sslHostname) {
RedisClient client = createClient(type, address, uri, config.getConnectTimeout(), config.getRetryInterval() * config.getRetryAttempts(), sslHostname);
RedisClient client = createClient(type, address, uri, config.getConnectTimeout(), config.getTimeout(), sslHostname);
return client;
}
@ -531,17 +516,18 @@ public class MasterSlaveConnectionManager implements ConnectionManager {
}
});
}
protected final void addEntry(Integer slot, MasterSlaveEntry entry) {
slot2entry.set(slot, entry);
entry.addSlotRange(slot);
MasterSlaveEntry oldEntry = slot2entry.getAndSet(slot, entry);
if (oldEntry != entry) {
entry.incReference();
}
client2entry.put(entry.getClient(), entry);
}
protected final MasterSlaveEntry removeEntry(Integer slot) {
MasterSlaveEntry entry = slot2entry.getAndSet(slot, null);
entry.removeSlotRange(slot);
if (entry.getSlotRanges().isEmpty()) {
if (entry.decReference() == 0) {
client2entry.remove(entry.getClient());
}
return entry;

@ -18,10 +18,8 @@ package org.redisson.connection;
import java.net.InetSocketAddress;
import java.net.URI;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import org.redisson.api.NodeType;
@ -32,7 +30,6 @@ import org.redisson.client.RedisPubSubConnection;
import org.redisson.client.protocol.CommandData;
import org.redisson.client.protocol.RedisCommand;
import org.redisson.cluster.ClusterConnectionManager;
import org.redisson.cluster.ClusterSlotRange;
import org.redisson.config.MasterSlaveServersConfig;
import org.redisson.config.ReadMode;
import org.redisson.config.SubscriptionMode;
@ -66,11 +63,12 @@ public class MasterSlaveEntry {
LoadBalancerManager slaveBalancer;
ClientConnectionsEntry masterEntry;
int references;
final MasterSlaveServersConfig config;
final ConnectionManager connectionManager;
final MasterConnectionPool writeConnectionPool;
final Set<Integer> slots = new HashSet<Integer>();
final MasterPubSubConnectionPool pubSubConnectionPool;
@ -78,12 +76,7 @@ public class MasterSlaveEntry {
String sslHostname;
public MasterSlaveEntry(Set<ClusterSlotRange> slotRanges, ConnectionManager connectionManager, MasterSlaveServersConfig config) {
for (ClusterSlotRange clusterSlotRange : slotRanges) {
for (int i = clusterSlotRange.getStartSlot(); i < clusterSlotRange.getEndSlot() + 1; i++) {
slots.add(i);
}
}
public MasterSlaveEntry(ConnectionManager connectionManager, MasterSlaveServersConfig config) {
this.connectionManager = connectionManager;
this.config = config;
@ -524,17 +517,17 @@ public class MasterSlaveEntry {
}
slaveBalancer.returnConnection(connection);
}
public void addSlotRange(Integer range) {
slots.add(range);
public void incReference() {
references++;
}
public void removeSlotRange(Integer range) {
slots.remove(range);
public int decReference() {
return --references;
}
public Set<Integer> getSlotRanges() {
return slots;
public int getReferences() {
return references;
}
@Override

@ -420,9 +420,8 @@ public class SentinelConnectionManager extends MasterSlaveConnectionManager {
}
@Override
protected MasterSlaveEntry createMasterSlaveEntry(MasterSlaveServersConfig config,
HashSet<ClusterSlotRange> slots) {
MasterSlaveEntry entry = new MasterSlaveEntry(slots, this, config);
protected MasterSlaveEntry createMasterSlaveEntry(MasterSlaveServersConfig config) {
MasterSlaveEntry entry = new MasterSlaveEntry(this, config);
List<RFuture<Void>> fs = entry.initSlaveBalancer(disconnectedSlaves);
for (RFuture<Void> future : fs) {
future.syncUninterruptibly();

@ -16,12 +16,10 @@
package org.redisson.connection;
import java.net.URI;
import java.util.Set;
import org.redisson.api.RFuture;
import org.redisson.client.RedisConnection;
import org.redisson.client.protocol.RedisCommand;
import org.redisson.cluster.ClusterSlotRange;
import org.redisson.config.MasterSlaveServersConfig;
/**
@ -31,8 +29,8 @@ import org.redisson.config.MasterSlaveServersConfig;
*/
public class SingleEntry extends MasterSlaveEntry {
public SingleEntry(Set<ClusterSlotRange> slotRanges, ConnectionManager connectionManager, MasterSlaveServersConfig config) {
super(slotRanges, connectionManager, config);
public SingleEntry(ConnectionManager connectionManager, MasterSlaveServersConfig config) {
super(connectionManager, config);
}
@Override

@ -71,4 +71,8 @@ public class EvictionScheduler {
}
}
public void remove(String name) {
tasks.remove(name);
}
}

@ -60,11 +60,11 @@ public class ScheduledTasksService extends TasksService {
"if redis.call('exists', KEYS[2]) == 0 then "
+ "local retryInterval = redis.call('get', KEYS[6]); "
+ "if retryInterval ~= false then "
+ "local time = tonumber(ARGV[4]) + tonumber(retryInterval);"
+ "local time = tonumber(ARGV[1]) + tonumber(retryInterval);"
+ "redis.call('zadd', KEYS[3], time, 'ff' .. ARGV[2]);"
+ "elseif tonumber(ARGV[5]) > 0 then "
+ "redis.call('set', KEYS[6], ARGV[5]);"
+ "local time = tonumber(ARGV[4]) + tonumber(ARGV[5]);"
+ "elseif tonumber(ARGV[4]) > 0 then "
+ "redis.call('set', KEYS[6], ARGV[4]);"
+ "local time = tonumber(ARGV[1]) + tonumber(ARGV[4]);"
+ "redis.call('zadd', KEYS[3], time, 'ff' .. ARGV[2]);"
+ "end; "
@ -81,7 +81,7 @@ public class ScheduledTasksService extends TasksService {
+ "end;"
+ "return 0;",
Arrays.<Object>asList(tasksCounterName, statusName, schedulerQueueName, schedulerChannelName, tasksName, tasksRetryIntervalName),
params.getStartTime(), request.getId(), encode(request), System.currentTimeMillis(), tasksRetryInterval);
params.getStartTime(), request.getId(), encode(request), tasksRetryInterval);
}
@Override
@ -102,8 +102,9 @@ public class ScheduledTasksService extends TasksService {
// remove from executor queue
+ "if task ~= false and (removed > 0 or removedScheduled > 0) then "
+ "if redis.call('decr', KEYS[3]) == 0 then "
+ "redis.call('del', KEYS[3], KEYS[7]);"
+ "redis.call('del', KEYS[3]);"
+ "if redis.call('get', KEYS[4]) == ARGV[2] then "
+ "redis.call('del', KEYS[7]);"
+ "redis.call('set', KEYS[4], ARGV[3]);"
+ "redis.call('publish', KEYS[5], ARGV[3]);"
+ "end;"

@ -63,7 +63,7 @@ import io.netty.util.concurrent.FutureListener;
*/
public class TasksRunnerService implements RemoteExecutorService {
private final Map<HashValue, Codec> codecs = new LRUCacheMap<HashValue, Codec>(500, 0, 0);
private static final Map<HashValue, Codec> codecs = new LRUCacheMap<HashValue, Codec>(500, 0, 0);
private final Codec codec;
private final String name;
@ -323,10 +323,12 @@ public class TasksRunnerService implements RemoteExecutorService {
+ "if scheduled == false then "
+ "redis.call('hdel', KEYS[4], ARGV[3]); "
+ "end;" +
"redis.call('zrem', KEYS[5], 'ff' .. ARGV[3]);" +
"if redis.call('decr', KEYS[1]) == 0 then "
+ "redis.call('del', KEYS[1], KEYS[6]);"
+ "redis.call('del', KEYS[1]);"
+ "if redis.call('get', KEYS[2]) == ARGV[1] then "
+ "redis.call('del', KEYS[6]);"
+ "redis.call('set', KEYS[2], ARGV[2]);"
+ "redis.call('publish', KEYS[3], ARGV[2]);"
+ "end;"

@ -167,8 +167,9 @@ public class TasksService extends BaseRemoteService {
// remove from executor queue
+ "if task ~= false and redis.call('exists', KEYS[3]) == 1 and redis.call('lrem', KEYS[1], 1, ARGV[1]) > 0 then "
+ "if redis.call('decr', KEYS[3]) == 0 then "
+ "redis.call('del', KEYS[3], KEYS[7]);"
+ "redis.call('del', KEYS[3]);"
+ "if redis.call('get', KEYS[4]) == ARGV[2] then "
+ "redis.call('del', KEYS[7]);"
+ "redis.call('set', KEYS[4], ARGV[3]);"
+ "redis.call('publish', KEYS[5], ARGV[3]);"
+ "end;"

@ -19,6 +19,7 @@ import java.util.concurrent.ThreadLocalRandom;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Test;
import org.redisson.api.RDestroyable;
import org.redisson.api.RLocalCachedMap;
import org.redisson.api.RMap;
import org.redisson.api.RMapCache;
@ -134,6 +135,12 @@ public abstract class BaseMapTest extends BaseTest {
}
private void destroy(RMap<?, ?> map) {
if (map instanceof RDestroyable) {
((RDestroyable) map).destroy();
}
}
@Test
public void testGetAllWithStringKeys() {
RMap<String, Integer> map = getMap("getAllStrings");
@ -148,6 +155,8 @@ public abstract class BaseMapTest extends BaseTest {
expectedMap.put("B", 200);
expectedMap.put("C", 300);
assertThat(filtered).isEqualTo(expectedMap);
destroy(map);
}
@Test
@ -166,12 +175,13 @@ public abstract class BaseMapTest extends BaseTest {
assertThat(next).isIn(new AbstractMap.SimpleEntry("A", "1"), new AbstractMap.SimpleEntry("B", "2"));
}
destroy(rmap);
redisson.shutdown();
}
@Test
public void testInteger() {
Map<Integer, Integer> map = getMap("test_int");
RMap<Integer, Integer> map = getMap("test_int");
map.put(1, 2);
map.put(3, 4);
@ -182,11 +192,12 @@ public abstract class BaseMapTest extends BaseTest {
Integer val2 = map.get(3);
assertThat(val2).isEqualTo(4);
destroy(map);
}
@Test
public void testLong() {
Map<Long, Long> map = getMap("test_long");
RMap<Long, Long> map = getMap("test_long");
map.put(1L, 2L);
map.put(3L, 4L);
@ -197,6 +208,7 @@ public abstract class BaseMapTest extends BaseTest {
Long val2 = map.get(3L);
assertThat(val2).isEqualTo(4);
destroy(map);
}
@Test
@ -224,6 +236,7 @@ public abstract class BaseMapTest extends BaseTest {
counter++;
}
assertThat(counter).isEqualTo(size);
destroy(rMap);
}
@Test
@ -257,23 +270,26 @@ public abstract class BaseMapTest extends BaseTest {
assertThat(rmap.entrySet()).containsExactlyElementsOf(map.entrySet());
assertThat(rmap.readAllEntrySet()).containsExactlyElementsOf(map.entrySet());
destroy(rmap);
}
@Test(expected = NullPointerException.class)
public void testNullValue() {
Map<Integer, String> map = getMap("simple12");
RMap<Integer, String> map = getMap("simple12");
destroy(map);
map.put(1, null);
}
@Test(expected = NullPointerException.class)
public void testNullKey() {
Map<Integer, String> map = getMap("simple12");
RMap<Integer, String> map = getMap("simple12");
destroy(map);
map.put(null, "1");
}
@Test
public void testSize() {
Map<SimpleKey, SimpleValue> map = getMap("simple");
RMap<SimpleKey, SimpleValue> map = getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
map.put(new SimpleKey("3"), new SimpleValue("4"));
@ -293,6 +309,7 @@ public abstract class BaseMapTest extends BaseTest {
map.remove(new SimpleKey("3"));
Assert.assertEquals(3, map.size());
destroy(map);
}
@Test
@ -301,8 +318,10 @@ public abstract class BaseMapTest extends BaseTest {
Assert.assertFalse(map.remove(1, 3));
map.put(4, 5);
Assert.assertTrue(map.remove(4, 5));
destroy(map);
}
@Test
public void testFastPutIfAbsent() throws Exception {
RMap<SimpleKey, SimpleValue> map = getMap("simple");
SimpleKey key = new SimpleKey("1");
@ -315,11 +334,12 @@ public abstract class BaseMapTest extends BaseTest {
SimpleValue value1 = new SimpleValue("4");
assertThat(map.fastPutIfAbsent(key1, value1)).isTrue();
assertThat(map.get(key1)).isEqualTo(value1);
destroy(map);
}
@Test
public void testPutAll() {
Map<Integer, String> map = getMap("simple");
RMap<Integer, String> map = getMap("simple");
map.put(1, "1");
map.put(2, "2");
map.put(3, "3");
@ -331,6 +351,7 @@ public abstract class BaseMapTest extends BaseTest {
map.putAll(joinMap);
assertThat(map.keySet()).containsOnly(1, 2, 3, 4, 5, 6);
destroy(map);
}
@Test
@ -340,15 +361,16 @@ public abstract class BaseMapTest extends BaseTest {
joinMap.put(i, "" + i);
}
Map<Integer, String> map = getMap("simple");
RMap<Integer, String> map = getMap("simple");
map.putAll(joinMap);
assertThat(map.size()).isEqualTo(joinMap.size());
destroy(map);
}
@Test
public void testPutGet() {
Map<SimpleKey, SimpleValue> map = getMap("simple");
RMap<SimpleKey, SimpleValue> map = getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
map.put(new SimpleKey("33"), new SimpleValue("44"));
map.put(new SimpleKey("5"), new SimpleValue("6"));
@ -358,11 +380,12 @@ public abstract class BaseMapTest extends BaseTest {
SimpleValue val2 = map.get(new SimpleKey("5"));
Assert.assertEquals("6", val2.getValue());
destroy(map);
}
@Test
public void testPutIfAbsent() throws Exception {
ConcurrentMap<SimpleKey, SimpleValue> map = getMap("simple");
RMap<SimpleKey, SimpleValue> map = getMap("simple");
SimpleKey key = new SimpleKey("1");
SimpleValue value = new SimpleValue("2");
map.put(key, value);
@ -373,6 +396,7 @@ public abstract class BaseMapTest extends BaseTest {
SimpleValue value1 = new SimpleValue("4");
Assert.assertNull(map.putIfAbsent(key1, value1));
Assert.assertEquals(value1, map.get(key1));
destroy(map);
}
@Test(timeout = 5000)
@ -392,6 +416,7 @@ public abstract class BaseMapTest extends BaseTest {
} catch (Exception e) {
e.printStackTrace();
}
destroy(map);
}
public static class SimpleObjectWithoutDefaultConstructor {
@ -413,7 +438,7 @@ public abstract class BaseMapTest extends BaseTest {
@Test
public void testReplaceOldValueFail() {
ConcurrentMap<SimpleKey, SimpleValue> map = getMap("simple");
RMap<SimpleKey, SimpleValue> map = getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
boolean res = map.replace(new SimpleKey("1"), new SimpleValue("43"), new SimpleValue("31"));
@ -421,11 +446,12 @@ public abstract class BaseMapTest extends BaseTest {
SimpleValue val1 = map.get(new SimpleKey("1"));
Assert.assertEquals("2", val1.getValue());
destroy(map);
}
@Test
public void testReplaceOldValueSuccess() {
ConcurrentMap<SimpleKey, SimpleValue> map = getMap("simple");
RMap<SimpleKey, SimpleValue> map = getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
boolean res = map.replace(new SimpleKey("1"), new SimpleValue("2"), new SimpleValue("3"));
@ -436,11 +462,12 @@ public abstract class BaseMapTest extends BaseTest {
SimpleValue val1 = map.get(new SimpleKey("1"));
Assert.assertEquals("3", val1.getValue());
destroy(map);
}
@Test
public void testReplaceValue() {
ConcurrentMap<SimpleKey, SimpleValue> map = getMap("simple");
RMap<SimpleKey, SimpleValue> map = getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
SimpleValue res = map.replace(new SimpleKey("1"), new SimpleValue("3"));
@ -448,12 +475,13 @@ public abstract class BaseMapTest extends BaseTest {
SimpleValue val1 = map.get(new SimpleKey("1"));
Assert.assertEquals("3", val1.getValue());
destroy(map);
}
@Test
public void testReplace() {
Map<SimpleKey, SimpleValue> map = getMap("simple");
RMap<SimpleKey, SimpleValue> map = getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
map.put(new SimpleKey("33"), new SimpleValue("44"));
map.put(new SimpleKey("5"), new SimpleValue("6"));
@ -464,11 +492,12 @@ public abstract class BaseMapTest extends BaseTest {
map.put(new SimpleKey("33"), new SimpleValue("abc"));
SimpleValue val2 = map.get(new SimpleKey("33"));
Assert.assertEquals("abc", val2.getValue());
destroy(map);
}
@Test
public void testContainsValue() {
Map<SimpleKey, SimpleValue> map = getMap("simple");
RMap<SimpleKey, SimpleValue> map = getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
map.put(new SimpleKey("33"), new SimpleValue("44"));
map.put(new SimpleKey("5"), new SimpleValue("6"));
@ -476,22 +505,24 @@ public abstract class BaseMapTest extends BaseTest {
Assert.assertTrue(map.containsValue(new SimpleValue("2")));
Assert.assertFalse(map.containsValue(new SimpleValue("441")));
Assert.assertFalse(map.containsValue(new SimpleKey("5")));
destroy(map);
}
@Test
public void testContainsKey() {
Map<SimpleKey, SimpleValue> map = getMap("simple");
RMap<SimpleKey, SimpleValue> map = getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
map.put(new SimpleKey("33"), new SimpleValue("44"));
map.put(new SimpleKey("5"), new SimpleValue("6"));
Assert.assertTrue(map.containsKey(new SimpleKey("33")));
Assert.assertFalse(map.containsKey(new SimpleKey("34")));
destroy(map);
}
@Test
public void testRemoveValueFail() {
ConcurrentMap<SimpleKey, SimpleValue> map = getMap("simple");
RMap<SimpleKey, SimpleValue> map = getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
boolean res = map.remove(new SimpleKey("2"), new SimpleValue("1"));
@ -502,11 +533,12 @@ public abstract class BaseMapTest extends BaseTest {
SimpleValue val1 = map.get(new SimpleKey("1"));
Assert.assertEquals("2", val1.getValue());
destroy(map);
}
@Test
public void testRemoveValue() {
ConcurrentMap<SimpleKey, SimpleValue> map = getMap("simple");
RMap<SimpleKey, SimpleValue> map = getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
boolean res = map.remove(new SimpleKey("1"), new SimpleValue("2"));
@ -516,11 +548,12 @@ public abstract class BaseMapTest extends BaseTest {
Assert.assertNull(val1);
Assert.assertEquals(0, map.size());
destroy(map);
}
@Test
public void testRemoveObject() {
Map<SimpleKey, SimpleValue> map = getMap("simple");
RMap<SimpleKey, SimpleValue> map = getMap("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
map.put(new SimpleKey("33"), new SimpleValue("44"));
map.put(new SimpleKey("5"), new SimpleValue("6"));
@ -530,6 +563,7 @@ public abstract class BaseMapTest extends BaseTest {
assertThat(map.remove(new SimpleKey("11"))).isNull();
assertThat(map.size()).isEqualTo(1);
destroy(map);
}
@Test
@ -543,6 +577,7 @@ public abstract class BaseMapTest extends BaseTest {
assertThat(map.remove(3)).isEqualTo(5);
assertThat(map.remove(10)).isNull();
assertThat(map.remove(7)).isEqualTo(8);
destroy(map);
}
@Test
@ -556,6 +591,7 @@ public abstract class BaseMapTest extends BaseTest {
assertThat(map.fastRemove(1, 3, 7)).isEqualTo(3);
Thread.sleep(1);
assertThat(map.size()).isEqualTo(1);
destroy(map);
}
@Test
@ -576,6 +612,7 @@ public abstract class BaseMapTest extends BaseTest {
}
assertThat(values.size()).isEqualTo(0);
destroy(map);
}
@Test
@ -586,6 +623,7 @@ public abstract class BaseMapTest extends BaseTest {
Assert.assertFalse(map.fastPut(1, 3));
assertThat(map.get(1)).isEqualTo(3);
Assert.assertEquals(1, map.size());
destroy(map);
}
@Test
@ -598,6 +636,7 @@ public abstract class BaseMapTest extends BaseTest {
Assert.assertEquals(1, map.size());
assertThat(map.get(1)).isEqualTo(3);
destroy(map);
}
@Test
@ -614,6 +653,7 @@ public abstract class BaseMapTest extends BaseTest {
assertThat(map).isEqualTo(testMap);
assertThat(testMap.hashCode()).isEqualTo(map.hashCode());
destroy(map);
}
@Test
@ -623,6 +663,7 @@ public abstract class BaseMapTest extends BaseTest {
assertThat(map.fastRemove()).isZero();
assertThat(map.size()).isEqualTo(1);
destroy(map);
}
@Test
@ -635,6 +676,7 @@ public abstract class BaseMapTest extends BaseTest {
assertThat(map.keySet("?0")).containsExactly("10", "20", "30");
assertThat(map.keySet("1")).isEmpty();
assertThat(map.keySet("10")).containsExactly("10");
destroy(map);
}
@Test
@ -647,6 +689,7 @@ public abstract class BaseMapTest extends BaseTest {
assertThat(map.values("?0")).containsExactly("100", "200", "300");
assertThat(map.values("1")).isEmpty();
assertThat(map.values("10")).containsExactly("100");
destroy(map);
}
@Test
@ -659,6 +702,7 @@ public abstract class BaseMapTest extends BaseTest {
assertThat(map.entrySet("?0")).containsExactly(new AbstractMap.SimpleEntry("10", "100"), new AbstractMap.SimpleEntry("20", "200"), new AbstractMap.SimpleEntry("30", "300"));
assertThat(map.entrySet("1")).isEmpty();
assertThat(map.entrySet("10")).containsExactly(new AbstractMap.SimpleEntry("10", "100"));
destroy(map);
}
@Test
@ -671,6 +715,7 @@ public abstract class BaseMapTest extends BaseTest {
assertThat(map.readAllKeySet().size()).isEqualTo(3);
Map<SimpleKey, SimpleValue> testMap = new HashMap<>(map);
assertThat(map.readAllKeySet()).containsOnlyElementsOf(testMap.keySet());
destroy(map);
}
@Test
@ -690,6 +735,7 @@ public abstract class BaseMapTest extends BaseTest {
Assert.assertEquals(10000, cnt);
assertThat(map).isEmpty();
Assert.assertEquals(0, map.size());
destroy(map);
}
@Test
@ -712,6 +758,7 @@ public abstract class BaseMapTest extends BaseTest {
}
Assert.assertEquals(10000, cnt);
assertThat(map.size()).isEqualTo(cnt - removed);
destroy(map);
}
@Test
@ -731,6 +778,7 @@ public abstract class BaseMapTest extends BaseTest {
Assert.assertEquals(10000, cnt);
assertThat(map).isEmpty();
Assert.assertEquals(0, map.size());
destroy(map);
}
@Test
@ -743,6 +791,7 @@ public abstract class BaseMapTest extends BaseTest {
assertThat(map.readAllKeySet().size()).isEqualTo(1000);
Map<SimpleKey, SimpleValue> testMap = new HashMap<>(map);
assertThat(map.readAllKeySet()).containsOnlyElementsOf(testMap.keySet());
destroy(map);
}
@Test
@ -755,6 +804,7 @@ public abstract class BaseMapTest extends BaseTest {
assertThat(map.readAllValues().size()).isEqualTo(3);
Map<SimpleKey, SimpleValue> testMap = new HashMap<>(map);
assertThat(map.readAllValues()).containsOnlyElementsOf(testMap.values());
destroy(map);
}
@Test
@ -771,6 +821,7 @@ public abstract class BaseMapTest extends BaseTest {
assertThat(s).isEqualTo(joinMap);
assertThat(map.size()).isEqualTo(joinMap.size());
destroy(map);
}
@Test
@ -787,6 +838,7 @@ public abstract class BaseMapTest extends BaseTest {
expectedMap.put(2, 200);
expectedMap.put(3, 300);
assertThat(filtered).isEqualTo(expectedMap);
destroy(map);
}
@Test
@ -797,6 +849,7 @@ public abstract class BaseMapTest extends BaseTest {
map.put("1", "1234");
assertThat(map.valueSize("4")).isZero();
assertThat(map.valueSize("1")).isEqualTo(6);
destroy(map);
}
@Test
@ -822,6 +875,7 @@ public abstract class BaseMapTest extends BaseTest {
expectedMap.put(8, 800);
assertThat(filtered.entrySet()).containsExactlyElementsOf(expectedMap.entrySet());
destroy(map);
}
@Test
@ -848,6 +902,7 @@ public abstract class BaseMapTest extends BaseTest {
expectedMap.put(8, 800);
assertThat(filtered.entrySet()).containsExactlyElementsOf(expectedMap.entrySet());
destroy(map);
}
@ -874,6 +929,7 @@ public abstract class BaseMapTest extends BaseTest {
assertThat(mapStr.addAndGet("1", 12)).isEqualTo(112);
assertThat(mapStr.get("1")).isEqualTo(112);
destroy(map);
}
protected abstract <K, V> RMap<K, V> getMap(String name);
@ -895,6 +951,7 @@ public abstract class BaseMapTest extends BaseTest {
assertThat(map.get("0")).isNull();
assertThat(map.get("1")).isEqualTo("11");
assertThat(map.get("0")).isNull(); // This line will never return anything and the test will hang
destroy(map);
}
@Test
@ -908,6 +965,7 @@ public abstract class BaseMapTest extends BaseTest {
Map<String, Integer> expected = new HashMap<>();
expected.put("1", 18);
assertThat(store).isEqualTo(expected);
destroy(map);
}
@ -925,6 +983,7 @@ public abstract class BaseMapTest extends BaseTest {
Map<String, String> expected = new HashMap<>();
expected.put("3", "33");
assertThat(store).isEqualTo(expected);
destroy(map);
}
@Test
@ -941,6 +1000,7 @@ public abstract class BaseMapTest extends BaseTest {
expected.put("2", "22");
expected.put("3", "33");
assertThat(store).isEqualTo(expected);
destroy(map);
}
@Test
@ -986,6 +1046,7 @@ public abstract class BaseMapTest extends BaseTest {
expected.put("1", "00");
expected.put("3", "33");
assertThat(store).isEqualTo(expected);
destroy(map);
}
@Test
@ -1009,6 +1070,7 @@ public abstract class BaseMapTest extends BaseTest {
expected2.put("2", "22");
expected2.put("3", "33");
assertThat(store).isEqualTo(expected2);
destroy(map);
}
@Test
@ -1024,6 +1086,7 @@ public abstract class BaseMapTest extends BaseTest {
expected.put("1", "11");
expected.put("2", "22");
assertThat(store).isEqualTo(expected);
destroy(map);
}
@Test
@ -1039,6 +1102,7 @@ public abstract class BaseMapTest extends BaseTest {
expected.put("1", "11");
expected.put("2", "22");
assertThat(store).isEqualTo(expected);
destroy(map);
}
@Test
@ -1057,6 +1121,7 @@ public abstract class BaseMapTest extends BaseTest {
expected.put("2", "22");
expected.put("3", "33");
assertThat(store).isEqualTo(expected);
destroy(map);
}
@ -1074,6 +1139,7 @@ public abstract class BaseMapTest extends BaseTest {
expected.put("2", "22");
expected.put("3", "33");
assertThat(store).isEqualTo(expected);
destroy(map);
}
@Test
@ -1099,6 +1165,7 @@ public abstract class BaseMapTest extends BaseTest {
assertThat(map.size()).isEqualTo(10);
assertThat(map.get("0")).isEqualTo("00");
assertThat(map.get("5")).isEqualTo("55");
destroy(map);
}
@Test
@ -1117,6 +1184,7 @@ public abstract class BaseMapTest extends BaseTest {
for (int i = 0; i < 100; i++) {
assertThat(map.containsKey("" + i)).isTrue();
}
destroy(map);
}
protected <K, V> MapWriter<K, V> createMapWriter(Map<K, V> map) {
@ -1185,6 +1253,7 @@ public abstract class BaseMapTest extends BaseTest {
expectedMap.put("3", "33");
assertThat(s).isEqualTo(expectedMap);
assertThat(map.size()).isEqualTo(4);
destroy(map);
}
}

@ -219,6 +219,11 @@ public class RedissonBucketTest extends BaseTest {
String value = "somevalue";
bucket.set(value);
Assert.assertEquals(value, bucket.get());
bucket.set(null);
bucket.set(null, 1, TimeUnit.DAYS);
assertThat(bucket.isExists()).isFalse();
}
@Test

@ -26,7 +26,6 @@ import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;
import org.junit.Test;
import org.redisson.RedissonLiveObjectServiceTest.TestEnum.MyEnum;
import org.redisson.api.RBlockingDeque;
import org.redisson.api.RBlockingQueue;
import org.redisson.api.RCascadeType;
@ -1548,15 +1547,15 @@ public class RedissonLiveObjectServiceTest extends BaseTest {
String id = "1";
TestEnum entry = new TestEnum();
entry.setId(id);
entry.setMyEnum1(MyEnum.A);
entry.setMyEnum1(TestEnum.MyEnum.A);
entry = liveObjectService.persist(entry);
TestEnum liveEntry = liveObjectService.get(TestEnum.class, id);
assertThat(liveEntry.getMyEnum1()).isEqualTo(MyEnum.A);
assertThat(liveEntry.getMyEnum1()).isEqualTo(TestEnum.MyEnum.A);
assertThat(liveEntry.getMyEnum2()).isNull();
entry.setMyEnum2(MyEnum.B);
assertThat(liveEntry.getMyEnum2()).isEqualTo(MyEnum.B);
entry.setMyEnum2(TestEnum.MyEnum.B);
assertThat(liveEntry.getMyEnum2()).isEqualTo(TestEnum.MyEnum.B);
}
@Test

@ -10,7 +10,6 @@ import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
@ -32,9 +31,24 @@ import org.redisson.client.codec.Codec;
import org.redisson.client.codec.DoubleCodec;
import org.redisson.client.codec.LongCodec;
import org.redisson.client.codec.StringCodec;
import org.redisson.eviction.EvictionScheduler;
import mockit.Deencapsulation;
public class RedissonMapCacheTest extends BaseMapTest {
@Test
public void testDestroy() {
RMapCache<String, String> cache = redisson.getMapCache("test");
EvictionScheduler evictionScheduler = ((Redisson)redisson).getEvictionScheduler();
Map<?, ?> map = Deencapsulation.getField(evictionScheduler, "tasks");
assertThat(map.isEmpty()).isFalse();
cache.destroy();
System.out.println("keys: " + map.keySet());
assertThat(map.isEmpty()).isTrue();
}
@Override
protected <K, V> RMap<K, V> getMap(String name) {
return redisson.getMapCache(name);
@ -68,6 +82,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
map.put("5", "6", 20, TimeUnit.SECONDS, 10, TimeUnit.SECONDS);
assertThat(map.remainTimeToLive("1")).isLessThan(9900);
map.destroy();
}
@Test
@ -83,6 +98,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
expected.put("1", "11");
expected.put("2", "22");
assertThat(store).isEqualTo(expected);
map.destroy();
}
@Test
@ -99,6 +115,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
expected.put("2", "22");
expected.put("3", "33");
assertThat(store).isEqualTo(expected);
map.destroy();
}
@Test
@ -114,6 +131,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
expected.put("1", "11");
expected.put("2", "22");
assertThat(store).isEqualTo(expected);
map.destroy();
}
@Test
@ -130,6 +148,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
expected.put("2", "22");
expected.put("3", "33");
assertThat(store).isEqualTo(expected);
map.destroy();
}
@Test
@ -277,6 +296,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
assertThat(map.size()).isEqualTo(maxSize.get());
assertThat(map.keySet()).containsExactly("58", "59", "60", "61", "62", "63");
map.destroy();
}
@ -285,6 +305,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
final RMapCache<String, String> map = redisson.getMapCache("testRMapCacheValues");
map.put("1234", "5678", 0, TimeUnit.MINUTES, 60, TimeUnit.MINUTES);
assertThat(map.values()).containsOnly("5678");
map.destroy();
}
@Test
@ -306,6 +327,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
Map<Integer, Integer> filteredAgain = map.getAll(new HashSet<Integer>(Arrays.asList(2, 3, 5)));
Assert.assertTrue(filteredAgain.isEmpty());
map.destroy();
}
@Test
@ -322,6 +344,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
expectedMap.put("B", 200);
expectedMap.put("C", 300);
Assert.assertEquals(expectedMap, filtered);
map.destroy();
}
@Test
@ -336,6 +359,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
Thread.sleep(1000);
assertThat(cache.keySet()).containsOnly("0", "2", "3");
cache.destroy();
}
@Test
@ -348,6 +372,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
Thread.sleep(500);
Assert.assertEquals(0, cache.size());
cache.destroy();
}
@Test
@ -360,6 +385,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
Thread.sleep(500);
Assert.assertEquals(0, cache.size());
cache.destroy();
}
@Test
@ -374,6 +400,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
Thread.sleep(500);
Assert.assertEquals(1, cache.size());
cache.destroy();
}
@Test
@ -389,6 +416,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
assertThat(map.entrySet()).containsAll(expected.entrySet());
assertThat(map).hasSize(3);
map.destroy();
}
@Test
@ -406,6 +434,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
Assert.assertFalse(map.keySet().contains(new SimpleKey("33")));
Assert.assertFalse(map.keySet().contains(new SimpleKey("44")));
Assert.assertTrue(map.keySet().contains(new SimpleKey("1")));
map.destroy();
}
@Test
@ -423,6 +452,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
Assert.assertFalse(map.values().contains(new SimpleValue("44")));
Assert.assertFalse(map.values().contains(new SimpleValue("33")));
Assert.assertTrue(map.values().contains(new SimpleValue("2")));
map.destroy();
}
@Test
@ -435,6 +465,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
assertThat(map.keySet("?0")).containsExactly("10", "20", "30");
assertThat(map.keySet("1")).isEmpty();
assertThat(map.keySet("10")).containsExactly("10");
map.destroy();
}
@Test
@ -447,6 +478,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
assertThat(map.values("?0")).containsExactly("100", "200", "300");
assertThat(map.values("1")).isEmpty();
assertThat(map.values("10")).containsExactly("100");
map.destroy();
}
@Test
@ -459,6 +491,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
assertThat(map.entrySet("?0")).containsExactly(new AbstractMap.SimpleEntry("10", "100"), new AbstractMap.SimpleEntry("20", "200"), new AbstractMap.SimpleEntry("30", "300"));
assertThat(map.entrySet("1")).isEmpty();
assertThat(map.entrySet("10")).containsExactly(new AbstractMap.SimpleEntry("10", "100"));
map.destroy();
}
@ -474,6 +507,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
Thread.sleep(1000);
Assert.assertFalse(map.containsValue(new SimpleValue("44")));
map.destroy();
}
@Test
@ -487,6 +521,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
Thread.sleep(1000);
Assert.assertFalse(map.containsKey(new SimpleKey("33")));
map.destroy();
}
@Test
@ -509,11 +544,12 @@ public class RedissonMapCacheTest extends BaseMapTest {
assertThat(map.remove(new SimpleKey("3"), new SimpleValue("4"))).isFalse();
assertThat(map.get(new SimpleKey("3"))).isNull();
map.destroy();
}
@Test
public void testRemoveValueFail() {
ConcurrentMap<SimpleKey, SimpleValue> map = redisson.getMapCache("simple");
RMapCache<SimpleKey, SimpleValue> map = redisson.getMapCache("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
boolean res = map.remove(new SimpleKey("2"), new SimpleValue("1"));
@ -524,12 +560,13 @@ public class RedissonMapCacheTest extends BaseMapTest {
SimpleValue val1 = map.get(new SimpleKey("1"));
Assert.assertEquals("2", val1.getValue());
map.destroy();
}
@Test
public void testReplaceOldValueFail() {
ConcurrentMap<SimpleKey, SimpleValue> map = redisson.getMapCache("simple");
RMapCache<SimpleKey, SimpleValue> map = redisson.getMapCache("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
boolean res = map.replace(new SimpleKey("1"), new SimpleValue("43"), new SimpleValue("31"));
@ -537,11 +574,12 @@ public class RedissonMapCacheTest extends BaseMapTest {
SimpleValue val1 = map.get(new SimpleKey("1"));
Assert.assertEquals("2", val1.getValue());
map.destroy();
}
@Test
public void testReplaceOldValueSuccess() {
ConcurrentMap<SimpleKey, SimpleValue> map = redisson.getMapCache("simple");
RMapCache<SimpleKey, SimpleValue> map = redisson.getMapCache("simple");
map.put(new SimpleKey("1"), new SimpleValue("2"));
boolean res = map.replace(new SimpleKey("1"), new SimpleValue("2"), new SimpleValue("3"));
@ -552,6 +590,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
SimpleValue val1 = map.get(new SimpleKey("1"));
Assert.assertEquals("3", val1.getValue());
map.destroy();
}
@Test
@ -566,6 +605,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
SimpleValue val1 = map.get(new SimpleKey("1"));
assertThat(val1).isNull();
map.destroy();
}
@Test
@ -582,6 +622,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
Thread.sleep(11000);
Assert.assertEquals(0, map.size());
map.destroy();
}
@ -605,6 +646,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
Thread.sleep(1000);
Assert.assertNull(map.get(new SimpleKey("33")));
map.destroy();
}
@Test
@ -632,6 +674,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
SimpleValue value1 = new SimpleValue("4");
Assert.assertNull(map.putIfAbsent(key1, value1, 2, TimeUnit.SECONDS));
Assert.assertEquals(value1, map.get(key1));
map.destroy();
}
@Test
@ -655,6 +698,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
Thread.sleep(500);
assertThat(map.fastPutIfAbsent(key2, new SimpleValue("32"))).isTrue();
assertThat(map.get(key2)).isEqualTo(new SimpleValue("32"));
map.destroy();
}
@ -671,6 +715,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
checkCreatedListener(map, 4, 1, () -> map.fastPutIfAbsent(4, 1));
checkCreatedListener(map, 15, 2, () -> map.fastPutIfAbsent(15, 2, 2, TimeUnit.SECONDS));
checkCreatedListener(map, 5, 0, () -> map.addAndGet(5, 0));
map.destroy();
}
private void checkCreatedListener(RMapCache<Integer, Integer> map, Integer key, Integer value, Runnable runnable) {
@ -692,6 +737,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
await().atMost(Duration.ONE_SECOND).untilTrue(ref);
map.removeListener(createListener1);
map.destroy();
}
@Test
@ -716,6 +762,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
map.put(5, 1);
checkUpdatedListener(map, 5, 4, 1, () -> map.addAndGet(5, 3));
map.destroy();
}
@ -727,6 +774,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
checkExpiredListener(map, 13, 2, () -> map.fastPut(13, 2, 2, TimeUnit.SECONDS));
checkExpiredListener(map, 14, 2, () -> map.putIfAbsent(14, 2, 2, TimeUnit.SECONDS));
checkExpiredListener(map, 15, 2, () -> map.fastPutIfAbsent(15, 2, 2, TimeUnit.SECONDS));
map.destroy();
}
private void checkExpiredListener(RMapCache<Integer, Integer> map, Integer key, Integer value, Runnable runnable) {
@ -785,6 +833,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
map.put(2, 1);
checkRemovedListener(map, 2, 1, () -> map.fastRemove(2));
map.destroy();
}
private void checkRemovedListener(RMapCache<Integer, Integer> map, Integer key, Integer value, Runnable runnable) {
@ -887,6 +936,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
map.clear();
map.destroy();
}
protected void testTTLExpiration(Consumer<RMapCache<String, Integer>> callback) throws InterruptedException {
@ -914,23 +964,25 @@ public class RedissonMapCacheTest extends BaseMapTest {
map.clear();
map.destroy();
}
@Test
public void testExpireOverwrite() throws InterruptedException, ExecutionException {
RMapCache<String, Integer> set = redisson.getMapCache("simple");
set.put("123", 3, 1, TimeUnit.SECONDS);
RMapCache<String, Integer> map = redisson.getMapCache("simple");
map.put("123", 3, 1, TimeUnit.SECONDS);
Thread.sleep(800);
set.put("123", 3, 1, TimeUnit.SECONDS);
map.put("123", 3, 1, TimeUnit.SECONDS);
Thread.sleep(800);
Assert.assertEquals(3, (int)set.get("123"));
Assert.assertEquals(3, (int)map.get("123"));
Thread.sleep(200);
Assert.assertFalse(set.containsKey("123"));
Assert.assertFalse(map.containsKey("123"));
map.destroy();
}
@Test
@ -938,6 +990,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
final RMapCache<String, String> map = redisson.getMapCache("testRMapCacheValues");
map.put("1234", "5678", 1, TimeUnit.MINUTES, 60, TimeUnit.MINUTES);
assertThat(map.values()).containsOnly("5678");
map.destroy();
}
@Test
@ -948,6 +1001,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
map.put(3, "43");
assertThat(map.readAllEntrySet()).isEqualTo(map.entrySet());
map.destroy();
}
@Test
@ -955,6 +1009,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
final RMapCache<String, String> map = redisson.getMapCache("testRMapCacheAllValues");
map.put("1234", "5678", 1, TimeUnit.MINUTES, 60, TimeUnit.MINUTES);
assertThat(map.readAllValues()).containsOnly("5678");
map.destroy();
}
@Test
@ -964,6 +1019,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
assertThat(mapCache.addAndGet("4", 1L)).isEqualTo(1L);
assertThat(mapCache.putIfAbsent("4", 0L)).isEqualTo(1L);
Assert.assertEquals(1L, mapCache.get("4"));
mapCache.destroy();
mapCache = redisson.getMapCache("test_put_if_absent_1", LongCodec.INSTANCE);
mapCache.putIfAbsent("4", 0L);
mapCache.addAndGet("4", 1L);
@ -978,6 +1034,8 @@ public class RedissonMapCacheTest extends BaseMapTest {
mapCache1.putIfAbsent("4", 1.23, 10000L, TimeUnit.SECONDS);
mapCache1.addAndGet("4", 1D);
Assert.assertEquals(2.23, mapCache1.get("4"));
mapCache.destroy();
mapCache1.destroy();
}
@ -1003,6 +1061,7 @@ public class RedissonMapCacheTest extends BaseMapTest {
Thread.sleep(550);
assertThat(map.fastPutIfAbsent(key, new SimpleValue("5"), 1, TimeUnit.SECONDS, 500, TimeUnit.MILLISECONDS)).isTrue();
map.destroy();
}
}

@ -16,7 +16,9 @@ import java.util.concurrent.TimeUnit;
import org.junit.Assert;
import org.junit.Test;
import org.redisson.api.RSetCache;
import org.redisson.codec.MsgPackJacksonCodec;
import org.redisson.eviction.EvictionScheduler;
import mockit.Deencapsulation;
public class RedissonSetCacheTest extends BaseTest {
@ -34,6 +36,17 @@ public class RedissonSetCacheTest extends BaseTest {
}
@Test
public void testDestroy() {
RSetCache<String> cache = redisson.getSetCache("test");
EvictionScheduler evictionScheduler = ((Redisson)redisson).getEvictionScheduler();
Map<?, ?> map = Deencapsulation.getField(evictionScheduler, "tasks");
assertThat(map.isEmpty()).isFalse();
cache.destroy();
assertThat(map.isEmpty()).isTrue();
}
@Test
public void testRemoveAll() {
RSetCache<Integer> set = redisson.getSetCache("set");
@ -44,6 +57,7 @@ public class RedissonSetCacheTest extends BaseTest {
assertThat(set.removeAll(Arrays.asList(1, 3))).isTrue();
assertThat(set.removeAll(Arrays.asList(1, 3))).isFalse();
assertThat(set).containsOnly(2);
set.destroy();
}
@Test
@ -53,12 +67,14 @@ public class RedissonSetCacheTest extends BaseTest {
set.add(1, 1, TimeUnit.SECONDS);
assertThat(set.delete()).isTrue();
assertThat(set.delete()).isFalse();
set.destroy();
}
@Test
public void testEmptyReadAll() {
RSetCache<Integer> set = redisson.getSetCache("set");
assertThat(set.readAll()).isEmpty();
set.destroy();
}
@Test
@ -72,6 +88,7 @@ public class RedissonSetCacheTest extends BaseTest {
map.remove(0);
set.add(map);
set.iterator().next();
set.destroy();
}
@Test
@ -81,6 +98,7 @@ public class RedissonSetCacheTest extends BaseTest {
RSetCache<SimpleBean> set = redisson.getSetCache("simple");
assertThat(set.add(sb)).isTrue();
Assert.assertEquals(sb.getLng(), set.iterator().next().getLng());
set.destroy();
}
@Test
@ -95,6 +113,7 @@ public class RedissonSetCacheTest extends BaseTest {
assertThat(set).doesNotContain("123");
assertThat(set.add("123", 1, TimeUnit.SECONDS)).isTrue();
set.destroy();
}
@ -106,6 +125,7 @@ public class RedissonSetCacheTest extends BaseTest {
assertThat(set.add("123", 3, TimeUnit.SECONDS)).isFalse();
Thread.sleep(2000);
assertThat(set.contains("123")).isTrue();
set.destroy();
}
@Test
@ -120,6 +140,7 @@ public class RedissonSetCacheTest extends BaseTest {
Thread.sleep(1000);
Assert.assertFalse(set.contains("4341"));
set.destroy();
}
@Test
@ -136,6 +157,7 @@ public class RedissonSetCacheTest extends BaseTest {
Thread.sleep(1000);
assertThat(set.contains("123")).isTrue();
set.destroy();
}
@ -154,6 +176,7 @@ public class RedissonSetCacheTest extends BaseTest {
Thread.sleep(300);
assertThat(set.contains("123")).isTrue();
set.destroy();
}
@Test
@ -174,6 +197,7 @@ public class RedissonSetCacheTest extends BaseTest {
Assert.assertFalse(set.contains(3));
assertThat(set).containsOnly(7);
Assert.assertEquals(1, set.size());
set.destroy();
}
@Test
@ -207,6 +231,7 @@ public class RedissonSetCacheTest extends BaseTest {
Assert.assertFalse(set.contains("4"));
Assert.assertFalse(set.contains("5"));
set.destroy();
}
@Test
@ -222,6 +247,7 @@ public class RedissonSetCacheTest extends BaseTest {
}
checkIterator(set, setCopy);
set.destroy();
}
private void checkIterator(Set<Long> set, Set<Long> setCopy) {
@ -247,6 +273,7 @@ public class RedissonSetCacheTest extends BaseTest {
Thread.sleep(500);
assertThat(set).containsOnly(1, 2);
Assert.assertEquals(2, set.size());
set.destroy();
}
@Test
@ -266,6 +293,7 @@ public class RedissonSetCacheTest extends BaseTest {
}
Assert.assertEquals(10000, cnt);
Assert.assertEquals(0, set.size());
set.destroy();
}
@Test
@ -278,6 +306,7 @@ public class RedissonSetCacheTest extends BaseTest {
Assert.assertTrue(set.containsAll(Collections.emptyList()));
Assert.assertTrue(set.containsAll(Arrays.asList(30, 11)));
Assert.assertFalse(set.containsAll(Arrays.asList(30, 711, 11)));
set.destroy();
}
@Test
@ -295,6 +324,7 @@ public class RedissonSetCacheTest extends BaseTest {
String[] strs = set.toArray(new String[0]);
assertThat(strs).containsOnly("1", "4", "5", "3");
set.destroy();
}
@Test
@ -312,6 +342,7 @@ public class RedissonSetCacheTest extends BaseTest {
Assert.assertFalse(set.contains(new TestObject("2", "3")));
Assert.assertTrue(set.contains(new TestObject("1", "2")));
Assert.assertFalse(set.contains(new TestObject("1", "9")));
set.destroy();
}
@Test
@ -325,6 +356,7 @@ public class RedissonSetCacheTest extends BaseTest {
set.add(new TestObject("5", "6"));
Assert.assertEquals(4, set.size());
set.destroy();
}
@Test
@ -339,6 +371,7 @@ public class RedissonSetCacheTest extends BaseTest {
set.add(5);
Assert.assertEquals(5, set.size());
set.destroy();
}
@Test
@ -347,6 +380,7 @@ public class RedissonSetCacheTest extends BaseTest {
set.add(1, 1, TimeUnit.SECONDS);
Thread.sleep(1005);
assertThat(set.readAll()).isEmpty();
set.destroy();
}
@Test
@ -359,6 +393,7 @@ public class RedissonSetCacheTest extends BaseTest {
set.add(5);
assertThat(set.readAll()).containsOnly(1, 2, 3, 4, 5);
set.destroy();
}
@Test
@ -372,6 +407,7 @@ public class RedissonSetCacheTest extends BaseTest {
Assert.assertTrue(set.retainAll(Collections.<Integer>emptyList()));
Assert.assertEquals(0, set.size());
set.destroy();
}
@Test
@ -382,6 +418,7 @@ public class RedissonSetCacheTest extends BaseTest {
Assert.assertFalse(set.retainAll(Arrays.asList(1, 2))); // nothing changed
assertThat(set).containsOnly(1, 2);
set.destroy();
}
@Test
@ -396,6 +433,7 @@ public class RedissonSetCacheTest extends BaseTest {
Thread.sleep(1000);
assertThat(cache).contains("0", "2", "3");
cache.destroy();
}
@Test
@ -408,6 +446,7 @@ public class RedissonSetCacheTest extends BaseTest {
Thread.sleep(500);
Assert.assertEquals(0, cache.size());
cache.destroy();
}
@Test
@ -420,6 +459,7 @@ public class RedissonSetCacheTest extends BaseTest {
Thread.sleep(500);
Assert.assertEquals(0, cache.size());
cache.destroy();
}
@Test
@ -434,6 +474,7 @@ public class RedissonSetCacheTest extends BaseTest {
Thread.sleep(500);
Assert.assertEquals(1, cache.size());
cache.destroy();
}
@Test
@ -446,6 +487,7 @@ public class RedissonSetCacheTest extends BaseTest {
Thread.sleep(11000);
Assert.assertEquals(0, cache.size());
cache.destroy();
}

@ -161,6 +161,7 @@ public class RedissonExecutorServiceTest extends BaseTest {
Thread.sleep(16000);
assertThat(redisson.getAtomicLong("counter").get()).isEqualTo(2);
executor.delete();
redisson.getKeys().delete("counter");
assertThat(redisson.getKeys().count()).isEqualTo(1);
}
@ -188,6 +189,7 @@ public class RedissonExecutorServiceTest extends BaseTest {
assertThat(executor.cancelTask(futureAsync.getTaskId())).isTrue();
assertThat(redisson.<Long>getBucket("executed2").get()).isBetween(1000L, Long.MAX_VALUE);
executor.delete();
redisson.getKeys().delete("executed1", "executed2");
assertThat(redisson.getKeys().count()).isZero();
}
@ -354,6 +356,7 @@ public class RedissonExecutorServiceTest extends BaseTest {
s4.get();
assertThat(redisson.getAtomicLong("runnableCounter").get()).isEqualTo(100L);
redisson.getExecutorService("test").delete();
redisson.getKeys().delete("runnableCounter", "counter");
assertThat(redisson.getKeys().count()).isZero();
}

@ -52,6 +52,23 @@ public class RedissonScheduledExecutorServiceTest extends BaseTest {
node.shutdown();
}
@Test
public void testDelay() throws InterruptedException {
RScheduledExecutorService executor = redisson.getExecutorService("test", ExecutorOptions.defaults().taskRetryInterval(5, TimeUnit.SECONDS));
long start = System.currentTimeMillis();
RScheduledFuture<?> f = executor.schedule(new ScheduledCallableTask(), 11, TimeUnit.SECONDS);
assertThat(f.awaitUninterruptibly(12000)).isTrue();
assertThat(System.currentTimeMillis() - start).isBetween(11000L, 11500L);
executor.scheduleWithFixedDelay(new IncrementRunnableTask("counter"), 0, 7, TimeUnit.SECONDS);
Thread.sleep(500);
assertThat(redisson.getAtomicLong("counter").get()).isEqualTo(1);
Thread.sleep(7000);
assertThat(redisson.getAtomicLong("counter").get()).isEqualTo(2);
Thread.sleep(7000);
assertThat(redisson.getAtomicLong("counter").get()).isEqualTo(3);
}
@Test
public void testTaskFailover() throws Exception {
AtomicInteger counter = new AtomicInteger();
@ -71,8 +88,10 @@ public class RedissonScheduledExecutorServiceTest extends BaseTest {
node.start();
RScheduledExecutorService executor = redisson.getExecutorService("test2", ExecutorOptions.defaults().taskRetryInterval(10, TimeUnit.SECONDS));
long start = System.currentTimeMillis();
RExecutorFuture<?> f = executor.schedule(new IncrementRunnableTask("counter"), 1, TimeUnit.SECONDS);
f.get();
f.syncUninterruptibly();
assertThat(System.currentTimeMillis() - start).isBetween(900L, 1200L);
assertThat(redisson.getAtomicLong("counter").get()).isEqualTo(1);
Thread.sleep(2000);
node.shutdown();
@ -146,10 +165,10 @@ public class RedissonScheduledExecutorServiceTest extends BaseTest {
@Test
public void testCronExpressionMultipleTasks() throws InterruptedException, ExecutionException {
RScheduledExecutorService executor = redisson.getExecutorService("test");
RScheduledExecutorService executor = redisson.getExecutorService("test", ExecutorOptions.defaults().taskRetryInterval(2, TimeUnit.SECONDS));
executor.schedule(new ScheduledRunnableTask("executed1"), CronSchedule.of("0/5 * * * * ?"));
executor.schedule(new ScheduledRunnableTask("executed2"), CronSchedule.of("0/1 * * * * ?"));
Thread.sleep(30200);
Thread.sleep(30000);
assertThat(redisson.getAtomicLong("executed1").get()).isEqualTo(6);
assertThat(redisson.getAtomicLong("executed2").get()).isEqualTo(30);
}
@ -163,6 +182,7 @@ public class RedissonScheduledExecutorServiceTest extends BaseTest {
Thread.sleep(2000);
assertThat(redisson.getAtomicLong("executed1").isExists()).isFalse();
executor.delete();
redisson.getKeys().delete("executed1");
assertThat(redisson.getKeys().count()).isZero();
}
@ -174,7 +194,7 @@ public class RedissonScheduledExecutorServiceTest extends BaseTest {
cancel(future1);
Thread.sleep(2000);
assertThat(redisson.getAtomicLong("executed1").isExists()).isFalse();
assertThat(executor.delete()).isFalse();
executor.delete();
redisson.getKeys().delete("executed1");
assertThat(redisson.getKeys().count()).isZero();
@ -193,6 +213,7 @@ public class RedissonScheduledExecutorServiceTest extends BaseTest {
assertThat(executor.cancelTask(futureAsync.getTaskId())).isTrue();
assertThat(redisson.<Long>getBucket("executed2").get()).isBetween(1000L, Long.MAX_VALUE);
executor.delete();
redisson.getKeys().delete("executed1", "executed2");
assertThat(redisson.getKeys().count()).isZero();
}
@ -216,6 +237,7 @@ public class RedissonScheduledExecutorServiceTest extends BaseTest {
Thread.sleep(3000);
assertThat(redisson.getAtomicLong("executed2").get()).isEqualTo(2);
executor.delete();
redisson.getKeys().delete("executed1", "executed2");
assertThat(redisson.getKeys().count()).isZero();
}
@ -244,6 +266,7 @@ public class RedissonScheduledExecutorServiceTest extends BaseTest {
Thread.sleep(3000);
assertThat(redisson.getAtomicLong("counter").get()).isEqualTo(3);
executor.delete();
redisson.getKeys().delete("counter", "executed1", "executed2");
assertThat(redisson.getKeys().count()).isZero();
}
@ -271,6 +294,7 @@ public class RedissonScheduledExecutorServiceTest extends BaseTest {
Thread.sleep(3000);
assertThat(redisson.getAtomicLong("executed1").get()).isEqualTo(5);
executor.delete();
redisson.getKeys().delete("executed1");
assertThat(redisson.getKeys().count()).isZero();
}
@ -293,6 +317,7 @@ public class RedissonScheduledExecutorServiceTest extends BaseTest {
assertThat(redisson.getAtomicLong("executed2").get()).isEqualTo(1);
assertThat(redisson.getAtomicLong("executed3").get()).isEqualTo(1);
executor.delete();
redisson.getKeys().delete("executed1", "executed2", "executed3");
assertThat(redisson.getKeys().count()).isZero();
}
@ -312,6 +337,7 @@ public class RedissonScheduledExecutorServiceTest extends BaseTest {
assertThat(redisson.getAtomicLong("executed2").get()).isEqualTo(1);
assertThat(redisson.getAtomicLong("executed3").get()).isEqualTo(1);
executor.delete();
redisson.getKeys().delete("executed1", "executed2", "executed3");
assertThat(redisson.getKeys().count()).isZero();
}
@ -325,6 +351,7 @@ public class RedissonScheduledExecutorServiceTest extends BaseTest {
assertThat(System.currentTimeMillis() - startTime).isBetween(5000L, 5200L);
assertThat(redisson.getAtomicLong("executed").get()).isEqualTo(1);
executor.delete();
redisson.getKeys().delete("executed");
assertThat(redisson.getKeys().count()).isZero();
}

Loading…
Cancel
Save