From 5207e39fc880951013846955ef228d8dc43b1a34 Mon Sep 17 00:00:00 2001 From: Mohd Sarfaraz Date: Sun, 5 Apr 2026 13:20:28 +0530 Subject: [PATCH 1/5] feat(lock): introduce LockConfiguration for configurable lock timin --- README.md | 41 +++++ .../phonepe/dlm/DistributedLockManager.java | 12 +- .../java/com/phonepe/dlm/lock/ILockable.java | 15 +- .../com/phonepe/dlm/lock/base/LockBase.java | 84 ++++++++-- .../dlm/lock/base/LockConfiguration.java | 116 +++++++++++++ .../dlm/lock/base/LockConfigurationTest.java | 152 ++++++++++++++++++ 6 files changed, 396 insertions(+), 24 deletions(-) create mode 100644 src/main/java/com/phonepe/dlm/lock/base/LockConfiguration.java create mode 100644 src/test/java/com/phonepe/dlm/lock/base/LockConfigurationTest.java diff --git a/README.md b/README.md index c81b995..97fbd6e 100644 --- a/README.md +++ b/README.md @@ -134,3 +134,44 @@ For XDC locks requiring strong consistency, opt for a multi-site Aerospike clust #### Notes A lock exists only within the scope of a Client represented by `CLIENT_ID`. + +--- + +## Configuring Lock Timing + +By default, every `LockBase` uses the library's built-in timing constants: + +| Parameter | Default | Description | +|-----------|---------|-------------| +| `lockTtl` | 90 s | How long the lock is held before the storage layer expires it automatically | +| `waitForLock` | 90 s | Maximum time a blocking `acquireLock` call waits for a contended lock | +| `retryInterval` | 1000 ms | Sleep interval between successive acquisition attempts | + +To customise these values supply a `LockConfiguration` to the `LockBase` builder using standard `Duration` values. Any value left unset falls back to the library default. + +```java +// Tight SLO service: short TTL, short wait, fast retry +LockConfiguration config = LockConfiguration.builder() + .lockTtl(Duration.ofSeconds(30)) // hold locks for 30 s + .waitForLock(Duration.ofSeconds(10)) // wait at most 10 s for a contended lock + .retryInterval(Duration.ofMillis(500)) // retry every 500 ms + .build(); + +DistributedLockManager lockManager = DistributedLockManager.builder() + .clientId("CLIENT_ID") + .farmId("FA1") + .lockBase(LockBase.builder() + .mode(LockMode.EXCLUSIVE) + .lockConfiguration(config) // <-- inject custom config + .lockStore(AerospikeStore.builder() + .aerospikeClient(aerospikeClient) + .namespace("NAMESPACE") + .setSuffix("distributed_lock") + .build()) + .build()) + .build(); +lockManager.initialize(); +``` + +> **Backward compatibility**: omitting `lockConfiguration(...)` from the builder is fully supported +> and produces identical behaviour to all previous library versions. diff --git a/src/main/java/com/phonepe/dlm/DistributedLockManager.java b/src/main/java/com/phonepe/dlm/DistributedLockManager.java index 8d3bd93..a092395 100644 --- a/src/main/java/com/phonepe/dlm/DistributedLockManager.java +++ b/src/main/java/com/phonepe/dlm/DistributedLockManager.java @@ -19,6 +19,7 @@ import com.phonepe.dlm.exception.ErrorCode; import com.phonepe.dlm.lock.Lock; import com.phonepe.dlm.lock.base.LockBase; +import com.phonepe.dlm.lock.base.LockConfiguration; import com.phonepe.dlm.lock.level.LockLevel; import java.time.Duration; @@ -42,7 +43,8 @@ public void initialize() { * This method attempts to acquire the lock immediately and throws exception if lock is unavailable * It does not wait if the lock is currently held by another thread. *

- * The lock will be acquired for default time period {@link LockBase#DEFAULT_LOCK_TTL_SECONDS} + * The lock will be held for the TTL configured in {@link LockBase}'s {@link LockConfiguration}, + * defaulting to {@link LockConfiguration#DEFAULT_LOCK_TTL} seconds. * * @param lock The lock to be acquired. * @throws DLMException with {@link ErrorCode#LOCK_UNAVAILABLE} if lock is already acquired @@ -68,8 +70,9 @@ public void tryAcquireLock(final Lock lock, final Duration duration) { * it will wait until the lock becomes available. * It blocks the thread until the lock is acquired. *

- * By default, timeout is {@link LockBase#DEFAULT_WAIT_FOR_LOCK_IN_SECONDS} - * The lock will be acquired for default time period {@link LockBase#DEFAULT_LOCK_TTL_SECONDS} + * By default, timeout is {@link LockConfiguration#DEFAULT_WAIT_FOR_LOCK} seconds and + * TTL is {@link LockConfiguration#DEFAULT_LOCK_TTL} seconds. Override both via + * {@link LockConfiguration} on the {@link LockBase}. * * @param lock The lock to be acquired. * @throws DLMException with {@link ErrorCode#LOCK_UNAVAILABLE} if lock is not available even after the timeout @@ -83,7 +86,8 @@ public void acquireLock(final Lock lock) { * it will wait until the lock becomes available. * It blocks the thread until the lock is acquired. *

- * By default, timeout is {@link LockBase#DEFAULT_WAIT_FOR_LOCK_IN_SECONDS} + * By default, timeout is {@link LockConfiguration#DEFAULT_WAIT_FOR_LOCK} seconds. Override + * via {@link LockConfiguration} on the {@link LockBase}. * * @param lock The lock to be acquired. * @param duration The lock duration in seconds for which lock will be held diff --git a/src/main/java/com/phonepe/dlm/lock/ILockable.java b/src/main/java/com/phonepe/dlm/lock/ILockable.java index edf1c6d..563a543 100644 --- a/src/main/java/com/phonepe/dlm/lock/ILockable.java +++ b/src/main/java/com/phonepe/dlm/lock/ILockable.java @@ -17,7 +17,8 @@ package com.phonepe.dlm.lock; import com.phonepe.dlm.exception.ErrorCode; -import com.phonepe.dlm.lock.base.LockBase; + +import com.phonepe.dlm.lock.base.LockConfiguration; import java.time.Duration; @@ -29,7 +30,9 @@ public interface ILockable { * This method attempts to acquire the lock immediately and throws exception if lock is unavailable * It does not wait if the lock is currently held by another thread. *

- * The lock will be acquired for default time period {@link LockBase#DEFAULT_LOCK_TTL_SECONDS} + * The lock will be acquired for the TTL configured via + * {@link LockConfiguration#getLockTtl}, defaulting to + * {@link LockConfiguration#DEFAULT_LOCK_TTL} seconds. * * @param lock The lock to be acquired. * @throws DLMException with {@link ErrorCode#LOCK_UNAVAILABLE} if lock is already acquired @@ -51,8 +54,9 @@ public interface ILockable { * it will wait until the lock becomes available. * It blocks the thread until the lock is acquired. *

- * By default, timeout is {@link LockBase#DEFAULT_WAIT_FOR_LOCK_IN_SECONDS} - * The lock will be acquired for default time period {@link LockBase#DEFAULT_LOCK_TTL_SECONDS} + * By default, timeout is {@link com.phonepe.dlm.lock.base.LockConfiguration#DEFAULT_WAIT_FOR_LOCK} seconds, + * and TTL is {@link com.phonepe.dlm.lock.base.LockConfiguration#DEFAULT_LOCK_TTL} seconds. + * Override both via {@link com.phonepe.dlm.lock.base.LockConfiguration}. * * @param lock The lock to be acquired. * @throws DLMException with {@link ErrorCode#LOCK_UNAVAILABLE} if lock is not available even after the timeout @@ -64,7 +68,8 @@ public interface ILockable { * it will wait until the lock becomes available. * It blocks the thread until the lock is acquired. *

- * By default, timeout is {@link LockBase#DEFAULT_WAIT_FOR_LOCK_IN_SECONDS} + * By default, timeout is {@link com.phonepe.dlm.lock.base.LockConfiguration#DEFAULT_WAIT_FOR_LOCK} seconds. + * Override via {@link com.phonepe.dlm.lock.base.LockConfiguration}. * * @param lock The lock to be acquired. * @param duration The lock duration in seconds for which lock will be held diff --git a/src/main/java/com/phonepe/dlm/lock/base/LockBase.java b/src/main/java/com/phonepe/dlm/lock/base/LockBase.java index 43bcd70..226e2ee 100644 --- a/src/main/java/com/phonepe/dlm/lock/base/LockBase.java +++ b/src/main/java/com/phonepe/dlm/lock/base/LockBase.java @@ -31,21 +31,69 @@ import java.time.Duration; import java.util.concurrent.atomic.AtomicBoolean; +/** + * Core implementation of the distributed locking contract defined by {@link ILockable}. + * + *

{@code LockBase} orchestrates lock acquisition and release by delegating storage operations + * to the configured {@link ILockStore}. Timing behaviour — TTL, wait timeout, and retry interval — + * is governed by the {@link LockConfiguration} supplied at construction time. When no configuration + * is provided the library falls back to {@link LockConfiguration}'s built-in defaults + * ({@link LockConfiguration#DEFAULT_LOCK_TTL}, + * {@link LockConfiguration#DEFAULT_WAIT_FOR_LOCK}, + * {@link LockConfiguration#DEFAULT_RETRY_INTERVAL}), preserving full backward + * compatibility. + * + *

Typical construction

+ *
{@code
+ * // Backward-compatible: omitting lockConfiguration uses library defaults.
+ * LockBase lockBase = LockBase.builder()
+ *         .mode(LockMode.EXCLUSIVE)
+ *         .lockStore(aerospikeStore)
+ *         .build();
+ *
+ * // Custom timing for a service with tighter SLOs.
+ * LockBase lockBase = LockBase.builder()
+ *         .mode(LockMode.EXCLUSIVE)
+ *         .lockStore(aerospikeStore)
+ *         .lockConfiguration(LockConfiguration.builder()
+ *                 .lockTtlSeconds(30)
+ *                 .waitForLockSeconds(10)
+ *                 .retryIntervalMillis(500L)
+ *                 .build())
+ *         .build();
+ * }
+ * + *

This class is thread-safe provided the supplied {@link ILockStore} is also thread-safe. + */ @Slf4j -@AllArgsConstructor -@Builder @Getter +@Builder +@AllArgsConstructor public class LockBase implements ILockable { - public static final Duration DEFAULT_LOCK_TTL_SECONDS = Duration.ofSeconds(90); - public static final Duration DEFAULT_WAIT_FOR_LOCK_IN_SECONDS = Duration.ofSeconds(90); - public static final int WAIT_TIME_FOR_NEXT_RETRY = 1000; // 1 second + /** + * The storage backend used to persist and remove lock records. + */ private final ILockStore lockStore; - private final LockMode mode; // Not implemented now, but can be leveraged in the future. + + /** + * The locking mode (e.g. {@link LockMode#EXCLUSIVE}). + * Not actively enforced today but reserved for future multi-mode support. + */ + private final LockMode mode; + + /** + * Timing configuration for this lock base instance. + *

+ * When not set via the builder, defaults to {@link LockConfiguration#builder() build()}, + * which applies the library-standard defaults (90 s TTL, 90 s wait, 1 000 ms retry). + */ + @Builder.Default + private final LockConfiguration lockConfiguration = LockConfiguration.builder().build(); @Override public void tryAcquireLock(final Lock lock) { - tryAcquireLock(lock, DEFAULT_LOCK_TTL_SECONDS); + tryAcquireLock(lock, lockConfiguration.getLockTtl()); } @Override @@ -55,12 +103,12 @@ public void tryAcquireLock(final Lock lock, final Duration duration) { @Override public void acquireLock(final Lock lock) { - acquireLock(lock, DEFAULT_LOCK_TTL_SECONDS, DEFAULT_WAIT_FOR_LOCK_IN_SECONDS); + acquireLock(lock, lockConfiguration.getLockTtl(), lockConfiguration.getWaitForLock()); } @Override public void acquireLock(final Lock lock, final Duration duration) { - acquireLock(lock, duration, DEFAULT_WAIT_FOR_LOCK_IN_SECONDS); + acquireLock(lock, duration, lockConfiguration.getWaitForLock()); } @Override @@ -77,7 +125,7 @@ public void acquireLock(final Lock lock, final Duration duration, final Duration throw e; } if (e.getErrorCode() == ErrorCode.LOCK_UNAVAILABLE) { - sleep(); + sleep(lockConfiguration.getRetryInterval()); continue; } throw e; @@ -85,7 +133,6 @@ public void acquireLock(final Lock lock, final Duration duration, final Duration } while (!success.get()); } - @Override public boolean releaseLock(final Lock lock) { if (lock.getAcquiredStatus().get()) { @@ -96,14 +143,21 @@ public boolean releaseLock(final Lock lock) { return false; } - private void writeToStore(final Lock lock, final Duration ttlSeconds) { - lockStore.write(lock.getLockId(), lock.getLockLevel(), lock.getFarmId(), ttlSeconds); + private void writeToStore(final Lock lock, final Duration ttl) { + lockStore.write(lock.getLockId(), lock.getLockLevel(), lock.getFarmId(), ttl); lock.getAcquiredStatus().compareAndSet(false, true); } - private static void sleep() { + /** + * Sleeps for the configured retry interval before the next acquisition attempt. + * + * @param retryInterval the duration to sleep + * @throws DLMException wrapping {@link InterruptedException} if the thread is interrupted + * while sleeping, with the interrupt status restored on the current thread + */ + private static void sleep(final Duration retryInterval) { try { - Thread.sleep(WAIT_TIME_FOR_NEXT_RETRY); + Thread.sleep(retryInterval.toMillis()); } catch (InterruptedException e) { log.error("Error sleeping the thread", e); Thread.currentThread().interrupt(); diff --git a/src/main/java/com/phonepe/dlm/lock/base/LockConfiguration.java b/src/main/java/com/phonepe/dlm/lock/base/LockConfiguration.java new file mode 100644 index 0000000..9a7caea --- /dev/null +++ b/src/main/java/com/phonepe/dlm/lock/base/LockConfiguration.java @@ -0,0 +1,116 @@ +/** + * Copyright (c) 2024 Original Author(s), PhonePe India Pvt. Ltd. + *

+ * 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 com.phonepe.dlm.lock.base; + +import lombok.Builder; +import lombok.Getter; + +import java.time.Duration; + +/** + * Immutable configuration encapsulating all timing parameters that govern lock-acquisition + * behaviour in the Distributed Lock Manager. + * + *

All parameters are expressed as {@link Duration} values. Any parameter left unset in the + * builder falls back to its corresponding library default via {@code @Builder.Default}, preserving + * full backward compatibility for callers that do not supply a {@code LockConfiguration}. + * + *

Default values

+ * + * + *

Usage

+ *
{@code
+ * // Use library defaults — identical behaviour to omitting lockConfiguration from the builder.
+ * LockConfiguration defaults = LockConfiguration.builder().build();
+ *
+ * // Custom configuration for a service with tighter SLOs.
+ * LockConfiguration custom = LockConfiguration.builder()
+ *         .lockTtl(Duration.ofSeconds(30))
+ *         .waitForLock(Duration.ofSeconds(10))
+ *         .retryInterval(Duration.ofMillis(500))
+ *         .build();
+ *
+ * DistributedLockManager lockManager = DistributedLockManager.builder()
+ *         .clientId("MY_SERVICE")
+ *         .farmId("FA1")
+ *         .lockBase(LockBase.builder()
+ *                 .mode(LockMode.EXCLUSIVE)
+ *                 .lockConfiguration(custom)
+ *                 .lockStore(aerospikeStore)
+ *                 .build())
+ *         .build();
+ * }
+ * + *

Instances of this class are immutable and therefore safe for concurrent use without + * external synchronisation. + */ +@Getter +@Builder +public final class LockConfiguration { + + /** + * Default lock time-to-live: 90 seconds. + *

+ * The lock is held for this duration before the storage layer expires it automatically, + * protecting against deadlocks caused by holders that crash or fail to release the lock. + */ + public static final Duration DEFAULT_LOCK_TTL = Duration.ofSeconds(90); + + /** + * Default maximum wait time for lock acquisition: 90 seconds. + *

+ * When a caller invokes a blocking {@code acquireLock} variant without specifying a timeout, + * the library retries for at most this duration before throwing a + * {@link com.phonepe.dlm.exception.DLMException} with + * {@link com.phonepe.dlm.exception.ErrorCode#LOCK_UNAVAILABLE}. + */ + public static final Duration DEFAULT_WAIT_FOR_LOCK = Duration.ofSeconds(90); + + /** + * Default polling interval between successive lock-acquisition retries: 1 second. + *

+ * When a lock is unavailable, the library sleeps for this duration before the next attempt. + * Tuning this value trades off CPU/network overhead against acquisition latency under + * contention. + */ + public static final Duration DEFAULT_RETRY_INTERVAL = Duration.ofMillis(1_000); + + /** + * The duration for which a successfully acquired lock is held before automatic expiry. + */ + @Builder.Default + private final Duration lockTtl = DEFAULT_LOCK_TTL; + + /** + * The maximum duration a blocking {@code acquireLock} call will wait for a contended lock. + */ + @Builder.Default + private final Duration waitForLock = DEFAULT_WAIT_FOR_LOCK; + + /** + * The sleep duration between successive acquisition attempts when a lock is unavailable. + */ + @Builder.Default + private final Duration retryInterval = DEFAULT_RETRY_INTERVAL; +} diff --git a/src/test/java/com/phonepe/dlm/lock/base/LockConfigurationTest.java b/src/test/java/com/phonepe/dlm/lock/base/LockConfigurationTest.java new file mode 100644 index 0000000..7186432 --- /dev/null +++ b/src/test/java/com/phonepe/dlm/lock/base/LockConfigurationTest.java @@ -0,0 +1,152 @@ +/** + * Copyright (c) 2024 Original Author(s), PhonePe India Pvt. Ltd. + *

+ * 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 com.phonepe.dlm.lock.base; + +import com.phonepe.dlm.DistributedLockManager; +import com.phonepe.dlm.lock.mode.LockMode; +import com.phonepe.dlm.lock.storage.ILockStore; +import org.junit.Test; +import org.mockito.Mockito; + +import java.time.Duration; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * Unit tests for {@link LockConfiguration}. + * + *

Covers: + *

+ */ +public class LockConfigurationTest { + + // ------------------------------------------------------------------------- + // Default value tests + // ------------------------------------------------------------------------- + + @Test + public void defaultBuildYieldsLibraryDefaults() { + final LockConfiguration config = LockConfiguration.builder().build(); + + assertEquals(LockConfiguration.DEFAULT_LOCK_TTL, config.getLockTtl()); + assertEquals(LockConfiguration.DEFAULT_WAIT_FOR_LOCK, config.getWaitForLock()); + assertEquals(LockConfiguration.DEFAULT_RETRY_INTERVAL, config.getRetryInterval()); + } + + @Test + public void defaultConstantsHaveExpectedValues() { + // Guard against accidental drift of the library defaults. + assertEquals(Duration.ofSeconds(90), LockConfiguration.DEFAULT_LOCK_TTL); + assertEquals(Duration.ofSeconds(90), LockConfiguration.DEFAULT_WAIT_FOR_LOCK); + assertEquals(Duration.ofMillis(1_000), LockConfiguration.DEFAULT_RETRY_INTERVAL); + } + + // ------------------------------------------------------------------------- + // Custom value tests + // ------------------------------------------------------------------------- + + @Test + public void customDurationValuesAreApplied() { + final LockConfiguration config = LockConfiguration.builder() + .lockTtl(Duration.ofSeconds(30)) + .waitForLock(Duration.ofSeconds(15)) + .retryInterval(Duration.ofMillis(500)) + .build(); + + assertEquals(Duration.ofSeconds(30), config.getLockTtl()); + assertEquals(Duration.ofSeconds(15), config.getWaitForLock()); + assertEquals(Duration.ofMillis(500), config.getRetryInterval()); + } + + @Test + public void partialConfigFallsBackToDefaultsForUnsetFields() { + // Only lockTtl is set; the other two should fall back to library defaults. + final LockConfiguration config = LockConfiguration.builder() + .lockTtl(Duration.ofSeconds(45)) + .build(); + + assertEquals(Duration.ofSeconds(45), config.getLockTtl()); + assertEquals(LockConfiguration.DEFAULT_WAIT_FOR_LOCK, config.getWaitForLock()); + assertEquals(LockConfiguration.DEFAULT_RETRY_INTERVAL, config.getRetryInterval()); + } + + // ------------------------------------------------------------------------- + // Backward-compatibility: LockBase builder without lockConfiguration + // ------------------------------------------------------------------------- + + @Test + public void lockBaseBuilderBackwardCompatibleWithoutConfiguration() { + final ILockStore mockStore = Mockito.mock(ILockStore.class); + + final LockBase lockBase = LockBase.builder() + .mode(LockMode.EXCLUSIVE) + .lockStore(mockStore) + .build(); + + assertNotNull(lockBase.getLockConfiguration()); + assertEquals(LockConfiguration.DEFAULT_LOCK_TTL, lockBase.getLockConfiguration().getLockTtl()); + assertEquals(LockConfiguration.DEFAULT_WAIT_FOR_LOCK, lockBase.getLockConfiguration().getWaitForLock()); + assertEquals(LockConfiguration.DEFAULT_RETRY_INTERVAL, lockBase.getLockConfiguration().getRetryInterval()); + } + + @Test + public void lockBaseHonoursCustomConfiguration() { + final ILockStore mockStore = Mockito.mock(ILockStore.class); + final LockConfiguration custom = LockConfiguration.builder() + .lockTtl(Duration.ofSeconds(20)) + .waitForLock(Duration.ofSeconds(5)) + .retryInterval(Duration.ofMillis(250)) + .build(); + + final LockBase lockBase = LockBase.builder() + .mode(LockMode.EXCLUSIVE) + .lockStore(mockStore) + .lockConfiguration(custom) + .build(); + + assertEquals(Duration.ofSeconds(20), lockBase.getLockConfiguration().getLockTtl()); + assertEquals(Duration.ofSeconds(5), lockBase.getLockConfiguration().getWaitForLock()); + assertEquals(Duration.ofMillis(250), lockBase.getLockConfiguration().getRetryInterval()); + } + + // ------------------------------------------------------------------------- + // DistributedLockManager builder backward compatibility + // ------------------------------------------------------------------------- + + @Test + public void distributedLockManagerBuilderBackwardCompatible() { + final ILockStore mockStore = Mockito.mock(ILockStore.class); + + final DistributedLockManager manager = DistributedLockManager.builder() + .clientId("CLIENT_ID") + .farmId("FA1") + .lockBase(LockBase.builder() + .mode(LockMode.EXCLUSIVE) + .lockStore(mockStore) + .build()) + .build(); + + assertNotNull(manager); + } +} From 2433efec8278f9f8ecc5673f21899529cb14fe80 Mon Sep 17 00:00:00 2001 From: Mohd Sarfaraz Date: Fri, 10 Apr 2026 12:08:19 +0530 Subject: [PATCH 2/5] Fix : java doc creation and remove unrequired tests --- .../java/com/phonepe/dlm/lock/ILockable.java | 2 +- .../com/phonepe/dlm/lock/base/LockBase.java | 12 +++++----- .../dlm/lock/base/LockConfiguration.java | 2 +- .../dlm/lock/base/LockConfigurationTest.java | 22 ------------------- 4 files changed, 8 insertions(+), 30 deletions(-) diff --git a/src/main/java/com/phonepe/dlm/lock/ILockable.java b/src/main/java/com/phonepe/dlm/lock/ILockable.java index 563a543..0a0f514 100644 --- a/src/main/java/com/phonepe/dlm/lock/ILockable.java +++ b/src/main/java/com/phonepe/dlm/lock/ILockable.java @@ -31,7 +31,7 @@ public interface ILockable { * It does not wait if the lock is currently held by another thread. *

* The lock will be acquired for the TTL configured via - * {@link LockConfiguration#getLockTtl}, defaulting to + * {@link LockConfiguration} (field: {@code lockTtl}), defaulting to * {@link LockConfiguration#DEFAULT_LOCK_TTL} seconds. * * @param lock The lock to be acquired. diff --git a/src/main/java/com/phonepe/dlm/lock/base/LockBase.java b/src/main/java/com/phonepe/dlm/lock/base/LockBase.java index 226e2ee..74bdb63 100644 --- a/src/main/java/com/phonepe/dlm/lock/base/LockBase.java +++ b/src/main/java/com/phonepe/dlm/lock/base/LockBase.java @@ -56,10 +56,10 @@ * .mode(LockMode.EXCLUSIVE) * .lockStore(aerospikeStore) * .lockConfiguration(LockConfiguration.builder() - * .lockTtlSeconds(30) - * .waitForLockSeconds(10) - * .retryIntervalMillis(500L) - * .build()) + * .lockTtl(Duration.ofSeconds(30)) + * .waitForLock(Duration.ofSeconds(10)) + * .retryInterval(Duration.ofMillis(500)) + * .build()) * .build(); * } * @@ -143,8 +143,8 @@ public boolean releaseLock(final Lock lock) { return false; } - private void writeToStore(final Lock lock, final Duration ttl) { - lockStore.write(lock.getLockId(), lock.getLockLevel(), lock.getFarmId(), ttl); + private void writeToStore(final Lock lock, final Duration ttlSeconds) { + lockStore.write(lock.getLockId(), lock.getLockLevel(), lock.getFarmId(), ttlSeconds); lock.getAcquiredStatus().compareAndSet(false, true); } diff --git a/src/main/java/com/phonepe/dlm/lock/base/LockConfiguration.java b/src/main/java/com/phonepe/dlm/lock/base/LockConfiguration.java index 9a7caea..46e6dea 100644 --- a/src/main/java/com/phonepe/dlm/lock/base/LockConfiguration.java +++ b/src/main/java/com/phonepe/dlm/lock/base/LockConfiguration.java @@ -53,7 +53,7 @@ * * DistributedLockManager lockManager = DistributedLockManager.builder() * .clientId("MY_SERVICE") - * .farmId("FA1") + * .farmId("MHX") * .lockBase(LockBase.builder() * .mode(LockMode.EXCLUSIVE) * .lockConfiguration(custom) diff --git a/src/test/java/com/phonepe/dlm/lock/base/LockConfigurationTest.java b/src/test/java/com/phonepe/dlm/lock/base/LockConfigurationTest.java index 7186432..888eab2 100644 --- a/src/test/java/com/phonepe/dlm/lock/base/LockConfigurationTest.java +++ b/src/test/java/com/phonepe/dlm/lock/base/LockConfigurationTest.java @@ -32,7 +32,6 @@ * *

Covers: *

* @@ -48,7 +48,7 @@ * LockConfiguration custom = LockConfiguration.builder() * .lockTtl(Duration.ofSeconds(30)) * .waitForLock(Duration.ofSeconds(10)) - * .retryInterval(Duration.ofMillis(500)) + * .sleepBetweenRetries(Duration.ofMillis(500)) * .build(); * * DistributedLockManager lockManager = DistributedLockManager.builder() @@ -94,7 +94,7 @@ public final class LockConfiguration { * Tuning this value trades off CPU/network overhead against acquisition latency under * contention. */ - public static final Duration DEFAULT_RETRY_INTERVAL = Duration.ofMillis(1_000); + public static final Duration DEFAULT_SLEEP_BETWEEN_RETRIES = Duration.ofMillis(1_000); /** * The duration for which a successfully acquired lock is held before automatic expiry. @@ -112,5 +112,5 @@ public final class LockConfiguration { * The sleep duration between successive acquisition attempts when a lock is unavailable. */ @Builder.Default - private final Duration retryInterval = DEFAULT_RETRY_INTERVAL; + private final Duration sleepBetweenRetries = DEFAULT_SLEEP_BETWEEN_RETRIES; } diff --git a/src/test/java/com/phonepe/dlm/lock/base/LockConfigurationTest.java b/src/test/java/com/phonepe/dlm/lock/base/LockConfigurationTest.java index 888eab2..d36ead6 100644 --- a/src/test/java/com/phonepe/dlm/lock/base/LockConfigurationTest.java +++ b/src/test/java/com/phonepe/dlm/lock/base/LockConfigurationTest.java @@ -16,7 +16,6 @@ package com.phonepe.dlm.lock.base; -import com.phonepe.dlm.DistributedLockManager; import com.phonepe.dlm.lock.mode.LockMode; import com.phonepe.dlm.lock.storage.ILockStore; import org.junit.Test; @@ -32,7 +31,6 @@ * *

Covers: *