Skip to content

Commit

Permalink
Merge pull request #1507 from lukas-krecan/jedis-extend
Browse files Browse the repository at this point in the history
Add ExtensibleLockProvider functionality to JedisLockProvider
  • Loading branch information
lukas-krecan authored Aug 24, 2023
2 parents b153d8e + bf49a9b commit 21fc6e1
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@

import net.javacrumbs.shedlock.core.AbstractSimpleLock;
import net.javacrumbs.shedlock.core.ClockProvider;
import net.javacrumbs.shedlock.core.ExtensibleLockProvider;
import net.javacrumbs.shedlock.core.LockConfiguration;
import net.javacrumbs.shedlock.core.LockProvider;
import net.javacrumbs.shedlock.core.SimpleLock;
import net.javacrumbs.shedlock.support.LockException;
import net.javacrumbs.shedlock.support.annotation.NonNull;
Expand All @@ -38,9 +38,9 @@
/**
* Uses Redis's `SET resource-name anystring NX PX max-lock-ms-time` as locking mechanism.
* <p>
* See https://redis.io/commands/set
* See <a href="https://redis.io/commands/set">Set command</a>
*/
public class JedisLockProvider implements LockProvider {
public class JedisLockProvider implements ExtensibleLockProvider {

private static final String KEY_PREFIX = "job-lock";
private static final String ENV_DEFAULT = "default";
Expand Down Expand Up @@ -86,20 +86,44 @@ public Optional<SimpleLock> lock(@NonNull LockConfiguration lockConfiguration) {
String rez = jedisTemplate.set(key, buildValue(), setParams().nx().px(expireTime));

if ("OK".equals(rez)) {
return Optional.of(new RedisLock(key, jedisTemplate, lockConfiguration));
return Optional.of(new RedisLock(key, this, lockConfiguration));
}

return Optional.empty();
}

private Optional<SimpleLock> extend(LockConfiguration lockConfiguration) {
long expireTime = getMsUntil(lockConfiguration.getLockAtMostUntil());

String key = buildKey(lockConfiguration.getName(), this.environment);

String rez = extendKeyExpiration(key, expireTime);

if ("OK".equals(rez)) {
return Optional.of(new RedisLock(key, this, lockConfiguration));
}

return Optional.empty();
}


private String extendKeyExpiration(String key, long expiration) {
return jedisTemplate.set(key, buildValue(), setParams().xx().px(expiration));
}

private void deleteKey(String key) {
jedisTemplate.del(key);
}


private static final class RedisLock extends AbstractSimpleLock {
private final String key;
private final JedisTemplate jedisTemplate;
private final JedisLockProvider jedisLockProvider;

private RedisLock(String key, JedisTemplate jedisTemplate, LockConfiguration lockConfiguration) {
private RedisLock(String key, JedisLockProvider jedisLockProvider, LockConfiguration lockConfiguration) {
super(lockConfiguration);
this.key = key;
this.jedisTemplate = jedisTemplate;
this.jedisLockProvider = jedisLockProvider;
}

@Override
Expand All @@ -109,14 +133,20 @@ public void doUnlock() {
// lock at least until is in the past
if (keepLockFor <= 0) {
try {
jedisTemplate.del(key);
jedisLockProvider.deleteKey(key);
} catch (Exception e) {
throw new LockException("Can not remove node", e);
}
} else {
jedisTemplate.set(key, buildValue(), setParams().xx().px(keepLockFor));
jedisLockProvider.extendKeyExpiration(key, keepLockFor);
}
}

@Override
@NonNull
protected Optional<SimpleLock> doExtend(@NonNull LockConfiguration newConfiguration) {
return jedisLockProvider.extend(newConfiguration);
}
}

private static long getMsUntil(Instant instant) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
*/
package net.javacrumbs.shedlock.provider.redis.jedis4;

import net.javacrumbs.shedlock.core.LockProvider;
import net.javacrumbs.shedlock.test.support.AbstractLockProviderIntegrationTest;
import net.javacrumbs.shedlock.core.ExtensibleLockProvider;
import net.javacrumbs.shedlock.test.support.AbstractExtensibleLockProviderIntegrationTest;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.testcontainers.junit.jupiter.Container;
Expand All @@ -37,8 +37,8 @@ public class JedisLockProviderIntegrationTest {
public static final RedisContainer redis = new RedisContainer(PORT);

@Nested
class Cluster extends AbstractLockProviderIntegrationTest {
private LockProvider lockProvider;
class Cluster extends AbstractExtensibleLockProviderIntegrationTest {
private ExtensibleLockProvider lockProvider;

private JedisCluster jedisCluster;

Expand All @@ -62,14 +62,14 @@ private String getLock(String lockName) {
}

@Override
protected LockProvider getLockProvider() {
protected ExtensibleLockProvider getLockProvider() {
return lockProvider;
}
}

@Nested
class Pool extends AbstractLockProviderIntegrationTest {
private LockProvider lockProvider;
class Pool extends AbstractExtensibleLockProviderIntegrationTest {
private ExtensibleLockProvider lockProvider;

private JedisPool jedisPool;

Expand Down Expand Up @@ -98,8 +98,9 @@ private String getLock(String lockName, Jedis jedis) {
}

@Override
protected LockProvider getLockProvider() {
protected ExtensibleLockProvider getLockProvider() {
return lockProvider;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ public void shouldNotBeAbleToExtendUnlockedLock() {
@Test
public void shouldNotBeAbleToExtendExpiredLock() {
Optional<SimpleLock> lock = getLockProvider().lock(lockConfig(LOCK_NAME1, Duration.ofMillis(1), Duration.ZERO));
sleepFor(Duration.ofMillis(1));
assertThat(lock).isNotEmpty();
sleepFor(Duration.ofMillis(2));

Optional<SimpleLock> newLock = lock.get().extend(Duration.ofSeconds(10), Duration.ZERO);
assertThat(newLock).isEmpty();
Expand Down

0 comments on commit 21fc6e1

Please sign in to comment.