use of org.redisson.api.RFuture in project redisson by redisson.
the class RedissonKeys method deleteAsync.
@Override
public RFuture<Long> deleteAsync(String... keys) {
if (!commandExecutor.getConnectionManager().isClusterMode()) {
return commandExecutor.writeAsync(null, RedisCommands.DEL, keys);
}
Map<MasterSlaveEntry, List<String>> range2key = new HashMap<MasterSlaveEntry, List<String>>();
for (String key : keys) {
int slot = commandExecutor.getConnectionManager().calcSlot(key);
for (MasterSlaveEntry entry : commandExecutor.getConnectionManager().getEntrySet()) {
List<String> list = range2key.get(entry);
if (list == null) {
list = new ArrayList<String>();
range2key.put(entry, list);
}
list.add(key);
}
}
final RPromise<Long> result = commandExecutor.getConnectionManager().newPromise();
final AtomicReference<Throwable> failed = new AtomicReference<Throwable>();
final AtomicLong count = new AtomicLong();
final AtomicLong executed = new AtomicLong(range2key.size());
FutureListener<List<?>> listener = new FutureListener<List<?>>() {
@Override
public void operationComplete(Future<List<?>> future) throws Exception {
if (future.isSuccess()) {
List<Long> result = (List<Long>) future.get();
for (Long res : result) {
count.addAndGet(res);
}
} else {
failed.set(future.cause());
}
checkExecution(result, failed, count, executed);
}
};
for (Entry<MasterSlaveEntry, List<String>> entry : range2key.entrySet()) {
// executes in batch due to CROSSLOT error
CommandBatchService executorService = new CommandBatchService(commandExecutor.getConnectionManager());
for (String key : entry.getValue()) {
executorService.writeAsync(entry.getKey(), null, RedisCommands.DEL, key);
}
RFuture<List<?>> future = executorService.executeAsync();
future.addListener(listener);
}
return result;
}
use of org.redisson.api.RFuture in project redisson by redisson.
the class RedissonBlockingFairQueue method tryPollAsync.
private void tryPollAsync(final long startTime, final long timeout, final TimeUnit unit, final RFuture<RedissonLockEntry> subscribeFuture, final RPromise<V> promise) {
if (promise.isDone()) {
unsubscribe(subscribeFuture);
return;
}
long spentTime = System.currentTimeMillis() - startTime;
long remainTime = unit.toMillis(timeout) - spentTime;
if (remainTime <= 0) {
unsubscribe(subscribeFuture);
promise.trySuccess(null);
return;
}
RFuture<Long> tryAcquireFuture = tryAcquireAsync();
tryAcquireFuture.addListener(new FutureListener<Long>() {
@Override
public void operationComplete(Future<Long> future) throws Exception {
if (!future.isSuccess()) {
unsubscribe(subscribeFuture);
promise.tryFailure(future.cause());
return;
}
Long currentTimeout = future.getNow();
if (currentTimeout == null) {
long spentTime = System.currentTimeMillis() - startTime;
long remainTime = unit.toMillis(timeout) - spentTime;
if (remainTime > 0) {
final RFuture<V> pollFuture = RedissonBlockingFairQueue.super.pollAsync(remainTime, TimeUnit.MILLISECONDS);
pollFuture.addListener(new FutureListener<V>() {
@Override
public void operationComplete(Future<V> future) throws Exception {
unsubscribe(subscribeFuture);
if (!future.isSuccess()) {
promise.tryFailure(future.cause());
return;
}
promise.trySuccess(future.getNow());
}
});
} else {
unsubscribe(subscribeFuture);
promise.trySuccess(null);
}
} else {
final RedissonLockEntry entry = getEntry();
synchronized (entry) {
if (entry.getLatch().tryAcquire()) {
tryPollAsync(startTime, timeout, unit, subscribeFuture, promise);
} else {
final AtomicBoolean executed = new AtomicBoolean();
final AtomicReference<Timeout> futureRef = new AtomicReference<Timeout>();
final Runnable listener = new Runnable() {
@Override
public void run() {
executed.set(true);
if (futureRef.get() != null) {
futureRef.get().cancel();
}
tryPollAsync(startTime, timeout, unit, subscribeFuture, promise);
}
};
entry.addListener(listener);
if (!executed.get()) {
long spentTime = System.currentTimeMillis() - startTime;
long remainTime = unit.toMillis(timeout) - spentTime;
Timeout scheduledFuture = commandExecutor.getConnectionManager().newTimeout(new TimerTask() {
@Override
public void run(Timeout t) throws Exception {
synchronized (entry) {
if (entry.removeListener(listener)) {
tryPollAsync(startTime, timeout, unit, subscribeFuture, promise);
}
}
}
}, remainTime, TimeUnit.MILLISECONDS);
futureRef.set(scheduledFuture);
}
}
}
}
}
;
});
}
use of org.redisson.api.RFuture in project redisson by redisson.
the class RedissonSemaphore method tryAcquireAsync.
@Override
public RFuture<Boolean> tryAcquireAsync(final int permits, long waitTime, TimeUnit unit) {
final RPromise<Boolean> result = newPromise();
final AtomicLong time = new AtomicLong(unit.toMillis(waitTime));
final long current = System.currentTimeMillis();
RFuture<Boolean> tryAcquireFuture = tryAcquireAsync(permits);
tryAcquireFuture.addListener(new FutureListener<Boolean>() {
@Override
public void operationComplete(Future<Boolean> future) throws Exception {
if (!future.isSuccess()) {
result.tryFailure(future.cause());
return;
}
if (future.getNow()) {
if (!result.trySuccess(true)) {
releaseAsync(permits);
}
return;
}
long elapsed = System.currentTimeMillis() - current;
time.addAndGet(-elapsed);
if (time.get() <= 0) {
result.trySuccess(false);
return;
}
final long current = System.currentTimeMillis();
final AtomicReference<Timeout> futureRef = new AtomicReference<Timeout>();
final RFuture<RedissonLockEntry> subscribeFuture = subscribe();
subscribeFuture.addListener(new FutureListener<RedissonLockEntry>() {
@Override
public void operationComplete(Future<RedissonLockEntry> future) throws Exception {
if (!future.isSuccess()) {
result.tryFailure(future.cause());
return;
}
if (futureRef.get() != null) {
futureRef.get().cancel();
}
long elapsed = System.currentTimeMillis() - current;
time.addAndGet(-elapsed);
if (time.get() < 0) {
unsubscribe(subscribeFuture);
result.trySuccess(false);
return;
}
tryAcquireAsync(time, permits, subscribeFuture, result);
}
});
if (!subscribeFuture.isDone()) {
Timeout scheduledFuture = commandExecutor.getConnectionManager().newTimeout(new TimerTask() {
@Override
public void run(Timeout timeout) throws Exception {
if (!subscribeFuture.isDone()) {
result.trySuccess(false);
}
}
}, time.get(), TimeUnit.MILLISECONDS);
futureRef.set(scheduledFuture);
}
}
});
return result;
}
use of org.redisson.api.RFuture in project redisson by redisson.
the class RedissonLock method tryLockAsync.
public RFuture<Boolean> tryLockAsync(final long waitTime, final long leaseTime, final TimeUnit unit, final long currentThreadId) {
final RPromise<Boolean> result = newPromise();
final AtomicLong time = new AtomicLong(unit.toMillis(waitTime));
final long currentTime = System.currentTimeMillis();
RFuture<Long> ttlFuture = tryAcquireAsync(leaseTime, unit, currentThreadId);
ttlFuture.addListener(new FutureListener<Long>() {
@Override
public void operationComplete(Future<Long> future) throws Exception {
if (!future.isSuccess()) {
result.tryFailure(future.cause());
return;
}
Long ttl = future.getNow();
// lock acquired
if (ttl == null) {
if (!result.trySuccess(true)) {
unlockAsync(currentThreadId);
}
return;
}
long elapsed = System.currentTimeMillis() - currentTime;
time.addAndGet(-elapsed);
if (time.get() <= 0) {
trySuccessFalse(currentThreadId, result);
return;
}
final long current = System.currentTimeMillis();
final AtomicReference<Timeout> futureRef = new AtomicReference<Timeout>();
final RFuture<RedissonLockEntry> subscribeFuture = subscribe(currentThreadId);
subscribeFuture.addListener(new FutureListener<RedissonLockEntry>() {
@Override
public void operationComplete(Future<RedissonLockEntry> future) throws Exception {
if (!future.isSuccess()) {
result.tryFailure(future.cause());
return;
}
if (futureRef.get() != null) {
futureRef.get().cancel();
}
long elapsed = System.currentTimeMillis() - current;
time.addAndGet(-elapsed);
tryLockAsync(time, leaseTime, unit, subscribeFuture, result, currentThreadId);
}
});
if (!subscribeFuture.isDone()) {
Timeout scheduledFuture = commandExecutor.getConnectionManager().newTimeout(new TimerTask() {
@Override
public void run(Timeout timeout) throws Exception {
if (!subscribeFuture.isDone()) {
subscribeFuture.cancel(false);
trySuccessFalse(currentThreadId, result);
}
}
}, time.get(), TimeUnit.MILLISECONDS);
futureRef.set(scheduledFuture);
}
}
});
return result;
}
use of org.redisson.api.RFuture in project redisson by redisson.
the class RedissonMultiLock method tryLock.
public boolean tryLock(long waitTime, long leaseTime, TimeUnit unit) throws InterruptedException {
long newLeaseTime = -1;
if (leaseTime != -1) {
newLeaseTime = waitTime * 2;
}
long time = System.currentTimeMillis();
long remainTime = -1;
if (waitTime != -1) {
remainTime = unit.toMillis(waitTime);
}
int failedLocksLimit = failedLocksLimit();
List<RLock> lockedLocks = new ArrayList<RLock>(locks.size());
for (ListIterator<RLock> iterator = locks.listIterator(); iterator.hasNext(); ) {
RLock lock = iterator.next();
boolean lockAcquired;
try {
if (waitTime == -1 && leaseTime == -1) {
lockAcquired = lock.tryLock();
} else {
long awaitTime = unit.convert(remainTime, TimeUnit.MILLISECONDS);
lockAcquired = lock.tryLock(awaitTime, newLeaseTime, unit);
}
} catch (Exception e) {
lockAcquired = false;
}
if (lockAcquired) {
lockedLocks.add(lock);
} else {
if (locks.size() - lockedLocks.size() == failedLocksLimit()) {
break;
}
if (failedLocksLimit == 0) {
unlockInner(lockedLocks);
if (waitTime == -1 && leaseTime == -1) {
return false;
}
failedLocksLimit = failedLocksLimit();
lockedLocks.clear();
// reset iterator
while (iterator.hasPrevious()) {
iterator.previous();
}
} else {
failedLocksLimit--;
}
}
if (remainTime != -1) {
remainTime -= (System.currentTimeMillis() - time);
time = System.currentTimeMillis();
if (remainTime <= 0) {
unlockInner(lockedLocks);
return false;
}
}
}
if (leaseTime != -1) {
List<RFuture<Boolean>> futures = new ArrayList<RFuture<Boolean>>(lockedLocks.size());
for (RLock rLock : lockedLocks) {
RFuture<Boolean> future = rLock.expireAsync(unit.toMillis(leaseTime), TimeUnit.MILLISECONDS);
futures.add(future);
}
for (RFuture<Boolean> rFuture : futures) {
rFuture.syncUninterruptibly();
}
}
return true;
}
Aggregations