diff --git a/README.md b/README.md
index ae1bbea14..936e10059 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-Redisson: Redis based In-Memory Data Grid for Java.
State of the Art Redis client
+Redisson: Redis based In-Memory Data Grid for Java.
State of the Art Redis Java client
====
[Quick start](https://github.com/redisson/redisson#quick-start) | [Documentation](https://github.com/redisson/redisson/wiki) | [Javadocs](http://www.javadoc.io/doc/org.redisson/redisson/3.8.2) | [Changelog](https://github.com/redisson/redisson/blob/master/CHANGELOG.md) | [Code examples](https://github.com/redisson/redisson-examples) | [FAQs](https://github.com/redisson/redisson/wiki/16.-FAQ) | [Report an issue](https://github.com/redisson/redisson/issues/new) | **[Redisson PRO](https://redisson.pro)**
@@ -12,17 +12,17 @@ Based on high-performance async and lock-free Java Redis client and [Netty](http
Features
================================
-* Replicated servers mode (also supports [AWS ElastiCache](http://docs.aws.amazon.com/AmazonElastiCache/latest/UserGuide/Replication.html) and [Azure Redis Cache](https://azure.microsoft.com/en-us/services/cache/)):
+* Replicated Redis servers mode (also supports [AWS ElastiCache](http://docs.aws.amazon.com/AmazonElastiCache/latest/UserGuide/Replication.html) and [Azure Redis Cache](https://azure.microsoft.com/en-us/services/cache/)):
1. automatic master server change discovery
-* Cluster servers mode (also supports [AWS ElastiCache Cluster](http://docs.aws.amazon.com/AmazonElastiCache/latest/UserGuide/Clusters.html) and [Azure Redis Cache](https://azure.microsoft.com/en-us/services/cache/)):
+* Clustered Redis servers mode (also supports [AWS ElastiCache Cluster](http://docs.aws.amazon.com/AmazonElastiCache/latest/UserGuide/Clusters.html) and [Azure Redis Cache](https://azure.microsoft.com/en-us/services/cache/)):
1. automatic master and slave servers discovery
2. automatic status and topology update
3. automatic slots change discovery
-* Sentinel servers mode:
+* Sentinel Redis servers mode:
1. automatic master, slave and sentinel servers discovery
2. automatic status and topology update
-* Master with Slave servers mode
-* Single server mode
+* Master with Slave Redis servers mode
+* Single Redis server mode
* Thread-safe implementation
* [Reactive Streams](https://github.com/redisson/redisson/wiki/3.-operations-execution#32-reactive-way) API
* [Asynchronous](https://github.com/redisson/redisson/wiki/3.-operations-execution#31-async-way) API
@@ -137,14 +137,14 @@ Config = ...
// 2. Create Redisson instance
RedissonClient redisson = Redisson.create(config);
-// 3. Get object you need
+// 3. Get Redis based object or service you need
RMap map = redisson.getMap("myMap");
RLock lock = redisson.getLock("myLock");
RExecutorService executor = redisson.getExecutorService("myExecutorService");
-// over 30 different objects and services ...
+// over 30 different Redis based objects and services ...
```
diff --git a/redisson-spring-boot-starter/README.md b/redisson-spring-boot-starter/README.md
index 384965187..1e91dc9d0 100644
--- a/redisson-spring-boot-starter/README.md
+++ b/redisson-spring-boot-starter/README.md
@@ -46,6 +46,8 @@ Usage
### 2. Add settings into `application.settings` file
+Common spring boot settings or Redisson settings could be used.
+
```properties
# common spring boot settings
diff --git a/redisson/src/main/java/org/redisson/Redisson.java b/redisson/src/main/java/org/redisson/Redisson.java
index aee5fd6cf..45df4ab55 100755
--- a/redisson/src/main/java/org/redisson/Redisson.java
+++ b/redisson/src/main/java/org/redisson/Redisson.java
@@ -124,6 +124,10 @@ public class Redisson implements RedissonClient {
evictionScheduler = new EvictionScheduler(connectionManager.getCommandExecutor());
}
+ public SemaphorePubSub getSemaphorePubSub() {
+ return semaphorePubSub;
+ }
+
public EvictionScheduler getEvictionScheduler() {
return evictionScheduler;
}
diff --git a/redisson/src/main/java/org/redisson/RedissonFairLock.java b/redisson/src/main/java/org/redisson/RedissonFairLock.java
index 407a1fdd3..257e05505 100644
--- a/redisson/src/main/java/org/redisson/RedissonFairLock.java
+++ b/redisson/src/main/java/org/redisson/RedissonFairLock.java
@@ -45,7 +45,7 @@ public class RedissonFairLock extends RedissonLock implements RLock {
private final String threadsQueueName;
private final String timeoutSetName;
- protected RedissonFairLock(CommandAsyncExecutor commandExecutor, String name) {
+ public RedissonFairLock(CommandAsyncExecutor commandExecutor, String name) {
super(commandExecutor, name);
this.commandExecutor = commandExecutor;
threadsQueueName = prefixName("redisson_lock_queue", name);
diff --git a/redisson/src/main/java/org/redisson/RedissonMap.java b/redisson/src/main/java/org/redisson/RedissonMap.java
index 18b6f4bd9..a50e0f103 100644
--- a/redisson/src/main/java/org/redisson/RedissonMap.java
+++ b/redisson/src/main/java/org/redisson/RedissonMap.java
@@ -33,11 +33,14 @@ import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
import org.redisson.api.MapOptions;
+import org.redisson.api.RCountDownLatch;
import org.redisson.api.MapOptions.WriteMode;
import org.redisson.api.RFuture;
import org.redisson.api.RLock;
import org.redisson.api.RMap;
+import org.redisson.api.RPermitExpirableSemaphore;
import org.redisson.api.RReadWriteLock;
+import org.redisson.api.RSemaphore;
import org.redisson.api.RedissonClient;
import org.redisson.api.mapreduce.RMapReduce;
import org.redisson.client.RedisClient;
@@ -106,7 +109,31 @@ public class RedissonMap extends RedissonExpirable implements RMap {
public RMapReduce mapReduce() {
return new RedissonMapReduce(this, redisson, commandExecutor.getConnectionManager());
}
+
+ @Override
+ public RPermitExpirableSemaphore getPermitExpirableSemaphore(K key) {
+ String lockName = getLockName(key, "permitexpirablesemaphore");
+ return new RedissonPermitExpirableSemaphore(commandExecutor, lockName, ((Redisson)redisson).getSemaphorePubSub());
+ }
+ @Override
+ public RSemaphore getSemaphore(K key) {
+ String lockName = getLockName(key, "semaphore");
+ return new RedissonSemaphore(commandExecutor, lockName, ((Redisson)redisson).getSemaphorePubSub());
+ }
+
+ @Override
+ public RCountDownLatch getCountDownLatch(K key) {
+ String lockName = getLockName(key, "countdownlatch");
+ return new RedissonCountDownLatch(commandExecutor, lockName);
+ }
+
+ @Override
+ public RLock getFairLock(K key) {
+ String lockName = getLockName(key, "fairlock");
+ return new RedissonFairLock(commandExecutor, lockName);
+ }
+
@Override
public RLock getLock(K key) {
String lockName = getLockName(key, "lock");
diff --git a/redisson/src/main/java/org/redisson/RedissonReactive.java b/redisson/src/main/java/org/redisson/RedissonReactive.java
index 6e8586411..eaf1e60e9 100644
--- a/redisson/src/main/java/org/redisson/RedissonReactive.java
+++ b/redisson/src/main/java/org/redisson/RedissonReactive.java
@@ -112,6 +112,22 @@ public class RedissonReactive implements RedissonReactiveClient {
codecProvider = config.getReferenceCodecProvider();
}
+ public EvictionScheduler getEvictionScheduler() {
+ return evictionScheduler;
+ }
+
+ public ConnectionManager getConnectionManager() {
+ return connectionManager;
+ }
+
+ public CommandReactiveService getCommandExecutor() {
+ return commandExecutor;
+ }
+
+ public SemaphorePubSub getSemaphorePubSub() {
+ return semaphorePubSub;
+ }
+
@Override
public RStreamReactive getStream(String name) {
return ReactiveProxyBuilder.create(commandExecutor, new RedissonStream(commandExecutor, name), RStreamReactive.class);
@@ -239,41 +255,41 @@ public class RedissonReactive implements RedissonReactiveClient {
@Override
public RSetMultimapReactive getSetMultimap(String name) {
return ReactiveProxyBuilder.create(commandExecutor, new RedissonSetMultimap(commandExecutor, name),
- new RedissonSetMultimapReactive(commandExecutor, name), RSetMultimapReactive.class);
+ new RedissonSetMultimapReactive(commandExecutor, name, this), RSetMultimapReactive.class);
}
@Override
public RSetMultimapReactive getSetMultimap(String name, Codec codec) {
return ReactiveProxyBuilder.create(commandExecutor, new RedissonSetMultimap(codec, commandExecutor, name),
- new RedissonSetMultimapReactive(codec, commandExecutor, name), RSetMultimapReactive.class);
+ new RedissonSetMultimapReactive(codec, commandExecutor, name, this), RSetMultimapReactive.class);
}
@Override
public RMapReactive getMap(String name) {
RedissonMap map = new RedissonMap(commandExecutor, name, null, null);
return ReactiveProxyBuilder.create(commandExecutor, map,
- new RedissonMapReactive(map), RMapReactive.class);
+ new RedissonMapReactive(map, this), RMapReactive.class);
}
@Override
public RMapReactive getMap(String name, Codec codec) {
RedissonMap map = new RedissonMap(codec, commandExecutor, name, null, null);
return ReactiveProxyBuilder.create(commandExecutor, map,
- new RedissonMapReactive(map), RMapReactive.class);
+ new RedissonMapReactive(map, this), RMapReactive.class);
}
@Override
public RSetReactive getSet(String name) {
RedissonSet set = new RedissonSet(commandExecutor, name, null);
return ReactiveProxyBuilder.create(commandExecutor, set,
- new RedissonSetReactive(set), RSetReactive.class);
+ new RedissonSetReactive(set, this), RSetReactive.class);
}
@Override
public RSetReactive getSet(String name, Codec codec) {
RedissonSet set = new RedissonSet(codec, commandExecutor, name, null);
return ReactiveProxyBuilder.create(commandExecutor, set,
- new RedissonSetReactive(set), RSetReactive.class);
+ new RedissonSetReactive(set, this), RSetReactive.class);
}
@Override
@@ -362,14 +378,14 @@ public class RedissonReactive implements RedissonReactiveClient {
public RSetCacheReactive getSetCache(String name) {
RSetCache set = new RedissonSetCache(evictionScheduler, commandExecutor, name, null);
return ReactiveProxyBuilder.create(commandExecutor, set,
- new RedissonSetCacheReactive(set), RSetCacheReactive.class);
+ new RedissonSetCacheReactive(set, this), RSetCacheReactive.class);
}
@Override
public RSetCacheReactive getSetCache(String name, Codec codec) {
RSetCache set = new RedissonSetCache(codec, evictionScheduler, commandExecutor, name, null);
return ReactiveProxyBuilder.create(commandExecutor, set,
- new RedissonSetCacheReactive(set), RSetCacheReactive.class);
+ new RedissonSetCacheReactive(set, this), RSetCacheReactive.class);
}
@Override
@@ -473,20 +489,18 @@ public class RedissonReactive implements RedissonReactiveClient {
new RedissonMapCacheReactive(map), RMapCacheReactive.class);
}
-
@Override
public RMapReactive getMap(String name, MapOptions options) {
RedissonMap map = new RedissonMap(commandExecutor, name, null, options);
return ReactiveProxyBuilder.create(commandExecutor, map,
- new RedissonMapReactive(map), RMapReactive.class);
+ new RedissonMapReactive(map, this), RMapReactive.class);
}
-
@Override
public RMapReactive getMap(String name, Codec codec, MapOptions options) {
RedissonMap map = new RedissonMap(codec, commandExecutor, name, null, options);
return ReactiveProxyBuilder.create(commandExecutor, map,
- new RedissonMapReactive(map), RMapReactive.class);
+ new RedissonMapReactive(map, this), RMapReactive.class);
}
@Override
diff --git a/redisson/src/main/java/org/redisson/RedissonRx.java b/redisson/src/main/java/org/redisson/RedissonRx.java
index 53938b1fc..49e73df7d 100644
--- a/redisson/src/main/java/org/redisson/RedissonRx.java
+++ b/redisson/src/main/java/org/redisson/RedissonRx.java
@@ -226,41 +226,41 @@ public class RedissonRx implements RedissonRxClient {
@Override
public RSetMultimapRx getSetMultimap(String name) {
return RxProxyBuilder.create(commandExecutor, new RedissonSetMultimap(commandExecutor, name),
- new RedissonSetMultimapRx(commandExecutor, name), RSetMultimapRx.class);
+ new RedissonSetMultimapRx(commandExecutor, name, this), RSetMultimapRx.class);
}
@Override
public RSetMultimapRx getSetMultimap(String name, Codec codec) {
return RxProxyBuilder.create(commandExecutor, new RedissonSetMultimap(codec, commandExecutor, name),
- new RedissonSetMultimapRx(codec, commandExecutor, name), RSetMultimapRx.class);
+ new RedissonSetMultimapRx(codec, commandExecutor, name, this), RSetMultimapRx.class);
}
@Override
public RMapRx getMap(String name) {
RedissonMap map = new RedissonMap(commandExecutor, name, null, null);
return RxProxyBuilder.create(commandExecutor, map,
- new RedissonMapRx(map), RMapRx.class);
+ new RedissonMapRx(map, this), RMapRx.class);
}
@Override
public RMapRx getMap(String name, Codec codec) {
RedissonMap map = new RedissonMap(codec, commandExecutor, name, null, null);
return RxProxyBuilder.create(commandExecutor, map,
- new RedissonMapRx(map), RMapRx.class);
+ new RedissonMapRx(map, this), RMapRx.class);
}
@Override
public RSetRx getSet(String name) {
RedissonSet set = new RedissonSet(commandExecutor, name, null);
return RxProxyBuilder.create(commandExecutor, set,
- new RedissonSetRx(set), RSetRx.class);
+ new RedissonSetRx(set, this), RSetRx.class);
}
@Override
public RSetRx getSet(String name, Codec codec) {
RedissonSet set = new RedissonSet(codec, commandExecutor, name, null);
return RxProxyBuilder.create(commandExecutor, set,
- new RedissonSetRx(set), RSetRx.class);
+ new RedissonSetRx(set, this), RSetRx.class);
}
@Override
@@ -350,14 +350,14 @@ public class RedissonRx implements RedissonRxClient {
public RSetCacheRx getSetCache(String name) {
RSetCache set = new RedissonSetCache(evictionScheduler, commandExecutor, name, null);
return RxProxyBuilder.create(commandExecutor, set,
- new RedissonSetCacheRx(set), RSetCacheRx.class);
+ new RedissonSetCacheRx(set, this), RSetCacheRx.class);
}
@Override
public RSetCacheRx getSetCache(String name, Codec codec) {
RSetCache set = new RedissonSetCache(codec, evictionScheduler, commandExecutor, name, null);
return RxProxyBuilder.create(commandExecutor, set,
- new RedissonSetCacheRx(set), RSetCacheRx.class);
+ new RedissonSetCacheRx(set, this), RSetCacheRx.class);
}
@Override
@@ -460,7 +460,7 @@ public class RedissonRx implements RedissonRxClient {
public RMapRx getMap(String name, MapOptions options) {
RedissonMap map = new RedissonMap(commandExecutor, name, null, options);
return RxProxyBuilder.create(commandExecutor, map,
- new RedissonMapRx(map), RMapRx.class);
+ new RedissonMapRx(map, this), RMapRx.class);
}
@@ -468,7 +468,7 @@ public class RedissonRx implements RedissonRxClient {
public RMapRx getMap(String name, Codec codec, MapOptions options) {
RedissonMap map = new RedissonMap(codec, commandExecutor, name, null, options);
return RxProxyBuilder.create(commandExecutor, map,
- new RedissonMapRx(map), RMapRx.class);
+ new RedissonMapRx(map, this), RMapRx.class);
}
@Override
diff --git a/redisson/src/main/java/org/redisson/RedissonSet.java b/redisson/src/main/java/org/redisson/RedissonSet.java
index 6d0c76fec..badf4cf9c 100644
--- a/redisson/src/main/java/org/redisson/RedissonSet.java
+++ b/redisson/src/main/java/org/redisson/RedissonSet.java
@@ -24,8 +24,12 @@ import java.util.List;
import java.util.Set;
import java.util.stream.Stream;
+import org.redisson.api.RCountDownLatch;
import org.redisson.api.RFuture;
import org.redisson.api.RLock;
+import org.redisson.api.RPermitExpirableSemaphore;
+import org.redisson.api.RReadWriteLock;
+import org.redisson.api.RSemaphore;
import org.redisson.api.RSet;
import org.redisson.api.RedissonClient;
import org.redisson.api.SortOrder;
@@ -603,20 +607,50 @@ public class RedissonSet extends RedissonExpirable implements RSet, ScanIt
return commandExecutor.writeAsync(getName(), codec, RedisCommands.SORT_TO, params.toArray());
}
- public String getLockName(Object value) {
+ public String getLockName(Object value, String suffix) {
ByteBuf state = encode(value);
try {
- return suffixName(getName(value), Hash.hash128toBase64(state) + ":lock");
+ return suffixName(getName(value), Hash.hash128toBase64(state) + ":" + suffix);
} finally {
state.release();
}
}
+
+ @Override
+ public RPermitExpirableSemaphore getPermitExpirableSemaphore(V value) {
+ String lockName = getLockName(value, "permitexpirablesemaphore");
+ return new RedissonPermitExpirableSemaphore(commandExecutor, lockName, ((Redisson)redisson).getSemaphorePubSub());
+ }
+
+ @Override
+ public RSemaphore getSemaphore(V value) {
+ String lockName = getLockName(value, "semaphore");
+ return new RedissonSemaphore(commandExecutor, lockName, ((Redisson)redisson).getSemaphorePubSub());
+ }
+
+ @Override
+ public RCountDownLatch getCountDownLatch(V value) {
+ String lockName = getLockName(value, "countdownlatch");
+ return new RedissonCountDownLatch(commandExecutor, lockName);
+ }
+
+ @Override
+ public RLock getFairLock(V value) {
+ String lockName = getLockName(value, "fairlock");
+ return new RedissonFairLock(commandExecutor, lockName);
+ }
@Override
public RLock getLock(V value) {
- String lockName = getLockName(value);
+ String lockName = getLockName(value, "lock");
return new RedissonLock(commandExecutor, lockName);
}
+
+ @Override
+ public RReadWriteLock getReadWriteLock(V value) {
+ String lockName = getLockName(value, "rw_lock");
+ return new RedissonReadWriteLock(commandExecutor, lockName);
+ }
@Override
public RFuture> scanIteratorAsync(String name, RedisClient client, long startPos,
diff --git a/redisson/src/main/java/org/redisson/RedissonSetCache.java b/redisson/src/main/java/org/redisson/RedissonSetCache.java
index 9c50b43b4..96d4c0ae9 100644
--- a/redisson/src/main/java/org/redisson/RedissonSetCache.java
+++ b/redisson/src/main/java/org/redisson/RedissonSetCache.java
@@ -25,8 +25,12 @@ import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;
+import org.redisson.api.RCountDownLatch;
import org.redisson.api.RFuture;
import org.redisson.api.RLock;
+import org.redisson.api.RPermitExpirableSemaphore;
+import org.redisson.api.RReadWriteLock;
+import org.redisson.api.RSemaphore;
import org.redisson.api.RSetCache;
import org.redisson.api.RedissonClient;
import org.redisson.api.mapreduce.RCollectionMapReduce;
@@ -367,20 +371,50 @@ public class RedissonSetCache extends RedissonExpirable implements RSetCache<
delete();
}
- public String getLockName(Object value) {
+ public String getLockName(Object value, String suffix) {
ByteBuf state = encode(value);
try {
- return suffixName(getName(value), Hash.hash128toBase64(state) + ":lock");
+ return suffixName(getName(value), Hash.hash128toBase64(state) + ":" + suffix);
} finally {
state.release();
}
}
+
+ @Override
+ public RPermitExpirableSemaphore getPermitExpirableSemaphore(V value) {
+ String lockName = getLockName(value, "permitexpirablesemaphore");
+ return new RedissonPermitExpirableSemaphore(commandExecutor, lockName, ((Redisson)redisson).getSemaphorePubSub());
+ }
+
+ @Override
+ public RSemaphore getSemaphore(V value) {
+ String lockName = getLockName(value, "semaphore");
+ return new RedissonSemaphore(commandExecutor, lockName, ((Redisson)redisson).getSemaphorePubSub());
+ }
+
+ @Override
+ public RCountDownLatch getCountDownLatch(V value) {
+ String lockName = getLockName(value, "countdownlatch");
+ return new RedissonCountDownLatch(commandExecutor, lockName);
+ }
+
+ @Override
+ public RLock getFairLock(V value) {
+ String lockName = getLockName(value, "fairlock");
+ return new RedissonFairLock(commandExecutor, lockName);
+ }
@Override
public RLock getLock(V value) {
- String lockName = getLockName(value);
+ String lockName = getLockName(value, "lock");
return new RedissonLock(commandExecutor, lockName);
}
+
+ @Override
+ public RReadWriteLock getReadWriteLock(V value) {
+ String lockName = getLockName(value, "rw_lock");
+ return new RedissonReadWriteLock(commandExecutor, lockName);
+ }
@Override
public void destroy() {
diff --git a/redisson/src/main/java/org/redisson/RedissonSetMultimapValues.java b/redisson/src/main/java/org/redisson/RedissonSetMultimapValues.java
index fd28a83e7..20b066712 100644
--- a/redisson/src/main/java/org/redisson/RedissonSetMultimapValues.java
+++ b/redisson/src/main/java/org/redisson/RedissonSetMultimapValues.java
@@ -24,8 +24,12 @@ import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;
+import org.redisson.api.RCountDownLatch;
import org.redisson.api.RFuture;
import org.redisson.api.RLock;
+import org.redisson.api.RPermitExpirableSemaphore;
+import org.redisson.api.RReadWriteLock;
+import org.redisson.api.RSemaphore;
import org.redisson.api.RSet;
import org.redisson.api.SortOrder;
import org.redisson.api.mapreduce.RCollectionMapReduce;
@@ -50,7 +54,8 @@ import org.redisson.command.CommandAsyncExecutor;
*/
public class RedissonSetMultimapValues extends RedissonExpirable implements RSet {
- private static final RedisCommand> EVAL_SSCAN = new RedisCommand>("EVAL", new ListMultiDecoder(new LongMultiDecoder(), new ObjectListReplayDecoder(), new ListScanResultReplayDecoder()), ValueType.MAP_VALUE);
+ private static final RedisCommand> EVAL_SSCAN = new RedisCommand>("EVAL",
+ new ListMultiDecoder(new LongMultiDecoder(), new ObjectListReplayDecoder(), new ListScanResultReplayDecoder()), ValueType.MAP_VALUE);
private final RSet set;
private final Object key;
@@ -469,6 +474,31 @@ public class RedissonSetMultimapValues extends RedissonExpirable implements R
Arrays.