From b35d289a22035941d886d5152885fd27de76bb49 Mon Sep 17 00:00:00 2001 From: Sascha Bieberstein Date: Mon, 12 Nov 2018 15:35:02 +0100 Subject: [PATCH] Adds api for passing a lock timeout when trying for a lock --- .../sirius/biz/locks/BasicLockManager.java | 6 ++++++ .../java/sirius/biz/locks/LockManager.java | 14 ++++++++++++-- src/main/java/sirius/biz/locks/Locks.java | 18 +++++++++++++++++- .../sirius/biz/locks/RedisLockManager.java | 7 ++++++- .../sirius/biz/locks/SmartLockManager.java | 5 +++++ 5 files changed, 46 insertions(+), 4 deletions(-) diff --git a/src/main/java/sirius/biz/locks/BasicLockManager.java b/src/main/java/sirius/biz/locks/BasicLockManager.java index 5175b9791..c43d6f44f 100644 --- a/src/main/java/sirius/biz/locks/BasicLockManager.java +++ b/src/main/java/sirius/biz/locks/BasicLockManager.java @@ -40,6 +40,12 @@ public boolean tryLock(@Nonnull String lockName, @Nullable Duration acquireTimeo } } + @Override + public boolean tryLock(@Nonnull String lockName, @Nullable Duration acquireTimeout, @Nonnull Duration lockTimeout) { + // Ignore lock timeout as its not supported here + return tryLock(lockName, acquireTimeout); + } + /** * If the lock is already aquired, this returns the initial amount of milliseconds to wait. * diff --git a/src/main/java/sirius/biz/locks/LockManager.java b/src/main/java/sirius/biz/locks/LockManager.java index 6e2e99f18..e9901acfb 100644 --- a/src/main/java/sirius/biz/locks/LockManager.java +++ b/src/main/java/sirius/biz/locks/LockManager.java @@ -25,12 +25,22 @@ public interface LockManager extends Named { * * @param lockName the name of the lock to acquire. * @param acquireTimeout the max time to wait for a lock. Used null to immediatelly return if a lock - * cannot - * be obtained. + * cannot be obtained. * @return true if the lock was acquired, false otherwise */ boolean tryLock(@Nonnull String lockName, @Nullable Duration acquireTimeout); + /** + * Tries to acquire the lock with the given name within the given interval. + * + * @param lockName the name of the lock to acquire. + * @param acquireTimeout the max time to wait for a lock. Used null to immediatelly return if a lock + * cannot be obtained. + * @param lockTimeout the max duration for which the lock will be kept before auto-releasing it. + * @return true if the lock was acquired, false otherwise + */ + boolean tryLock(@Nonnull String lockName, @Nullable Duration acquireTimeout, @Nonnull Duration lockTimeout); + /** * Determines if the lock is currently being locked. * diff --git a/src/main/java/sirius/biz/locks/Locks.java b/src/main/java/sirius/biz/locks/Locks.java index 55232aebb..d6bb285d7 100644 --- a/src/main/java/sirius/biz/locks/Locks.java +++ b/src/main/java/sirius/biz/locks/Locks.java @@ -55,6 +55,21 @@ public boolean tryLock(@Nonnull String lockName, @Nullable Duration acquireTimeo return manager.tryLock(lockName, acquireTimeout); } + /** + * Tries to acquire the given lock in the given timeslot. + *

+ * A sane value for the timeout might be in the range of 5-50s, highly depending on the algorithm + * being protected by the lock. If the value is null, no retries will be performed. + * + * @param lockName the name of the lock to acquire + * @param acquireTimeout the max duration during which retires will be performed + * @param lockTimeout the max duration for which the lock will be kept before auto-releasing it + * @return true if the lock was acquired, false otherwise + */ + public boolean tryLock(@Nonnull String lockName, @Nullable Duration acquireTimeout, @Nonnull Duration lockTimeout) { + return manager.tryLock(lockName, acquireTimeout, lockTimeout); + } + /** * Boilerplate method to perform the given task while holding the given lock. *

@@ -114,7 +129,8 @@ public void gather(MetricsCollector collector) { LocalDateTime limitForAcquired = LocalDateTime.now().minus(LONG_RUNNING_LOGS_THRESHOLD); collector.metric("locks_count", "locks-count", "Active Locks", locks.size(), null); - collector.metric("locks_long_running","locks-long-running", + collector.metric("locks_long_running", + "locks-long-running", "Long locks", locks.stream().filter(l -> l.getAcquired().isBefore(limitForAcquired)).count(), null); diff --git a/src/main/java/sirius/biz/locks/RedisLockManager.java b/src/main/java/sirius/biz/locks/RedisLockManager.java index 41dc2403b..a24c8d53e 100644 --- a/src/main/java/sirius/biz/locks/RedisLockManager.java +++ b/src/main/java/sirius/biz/locks/RedisLockManager.java @@ -40,7 +40,12 @@ public String getName() { @Override public boolean tryLock(@Nonnull String lockName, @Nullable Duration acquireTimeout) { - return redis.tryLock(lockName, acquireTimeout, Duration.ofMinutes(30)); + return tryLock(lockName, acquireTimeout, Duration.ofMinutes(30)); + } + + @Override + public boolean tryLock(@Nonnull String lockName, @Nullable Duration acquireTimeout, @Nonnull Duration lockTimeout) { + return redis.tryLock(lockName, acquireTimeout, lockTimeout); } @Override diff --git a/src/main/java/sirius/biz/locks/SmartLockManager.java b/src/main/java/sirius/biz/locks/SmartLockManager.java index 9efd23e80..7aac4602f 100644 --- a/src/main/java/sirius/biz/locks/SmartLockManager.java +++ b/src/main/java/sirius/biz/locks/SmartLockManager.java @@ -64,6 +64,11 @@ public boolean tryLock(@Nonnull String lockName, @Nullable Duration acquireTimeo return getDelegate().tryLock(lockName, acquireTimeout); } + @Override + public boolean tryLock(@Nonnull String lockName, @Nullable Duration acquireTimeout, @Nonnull Duration lockTimeout) { + return getDelegate().tryLock(lockName, acquireTimeout, lockTimeout); + } + @Override public boolean isLocked(@Nonnull String lock) { return getDelegate().isLocked(lock);