public class BroadcastingLock extends Object
Lock by internally broadcasting releasing events.
Since it is broadcasting, it gets slower as the concurrency increases. But its
performance is comparable to ReactiveLock within ~100 concurrency, which
is still not that likely to get surmounted easily.
| Constructor and Description |
|---|
BroadcastingLock() |
| Modifier and Type | Method and Description |
|---|---|
boolean |
isLocked()
Checks whether this lock is locked (or has reached the max lock holders)
|
Mono<Void> |
lock()
Get a
Mono that emits success only after acquiring the lock |
<T> Mono<T> |
lockOnNext(Mono<T> mono)
Try to acquire the lock on the next element before propagating
|
LockHandle |
tryLock()
Immediately requests to hold the lock.
|
Mono<Void> |
tryLock(Duration duration)
Tries to acquire the lock, or stop and propagate a
TimeoutException downstream after
certain duration. |
void |
unlock()
Unlocks
|
<T> Mono<T> |
unlockOnEmpty(Mono<T> mono)
Release the lock with
Mono.switchIfEmpty(Mono) |
<T> Mono<T> |
unlockOnError(Mono<T> mono)
Release the lock with
Mono.doOnError(Consumer) before propagating |
<T> Mono<T> |
unlockOnNext(Mono<T> mono)
Release the lock with
Mono.doOnNext(Consumer) before propagating |
<T> Mono<T> |
unlockOnTerminate(Mono<T> mono)
Release the lock with
Mono.doOnTerminate(Runnable) before propagating |
<T> Flux<T> |
withLock(Supplier<Publisher<T>> scoped)
Automatically acquires the lock, executes the function and unlocks.
|
public LockHandle tryLock()
Lock
See LockHandle. Subscribe to LockHandle.mono() to get informed
when the lock becomes available.
To properly unlock, you are suggested to handle all cases including completing
without error, failing with errors or the whole Mono or Flux getting
cancelled. You might want to use Lock.withLock(Supplier) to save yourself from
the boilerplate, which internally uses Flux.using(Callable, Function, Consumer)
to LockHandle.cancel() or Lock.unlock() accordingly.
public boolean isLocked()
LockYou should not rely on the result of this due to possible concurrent operations.
public void unlock()
LockUsage:
Lock lock = new ReactiveLock(); /* Or other locks */
mono
.transform(lock::lockOnNext)
.flatMap(item -> {
/* Some processing */
lock.unlock();
return Mono.just(item);
})
.block();
public Mono<Void> tryLock(Duration duration)
LockTimeoutException downstream after
certain duration.public Mono<Void> lock()
LockMono that emits success only after acquiring the lockpublic <T> Flux<T> withLock(Supplier<Publisher<T>> scoped)
Lock
It handles all cases including when the Flux completes without error (empty or not),
fails with errors, or gets cancelled middle way.
public <T> Mono<T> lockOnNext(Mono<T> mono)
LocklockOnNext in interface LockT - the generic type of Monomono - the Mono, of which the next value will require locking to propagateMonopublic <T> Mono<T> unlockOnTerminate(Mono<T> mono)
LockMono.doOnTerminate(Runnable) before propagatingunlockOnTerminate in interface LockT - the generic type of Monomono - the Mono, of which the termination signal will require unlocking to propagateMonopublic <T> Mono<T> unlockOnNext(Mono<T> mono)
LockMono.doOnNext(Consumer) before propagatingunlockOnNext in interface LockT - the generic type of Monomono - the Mono, of which the next value will require unlocking to propagateMonopublic <T> Mono<T> unlockOnEmpty(Mono<T> mono)
LockMono.switchIfEmpty(Mono)unlockOnEmpty in interface LockT - the generic type of Monomono - the Mono, of which the signal, when Mono is empty, will require unlocking to propagateMonopublic <T> Mono<T> unlockOnError(Mono<T> mono)
LockMono.doOnError(Consumer) before propagatingunlockOnError in interface LockT - the generic type of Monomono - the Mono, of which the next error will require unlocking to propagateMono