All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.javacrumbs.shedlock.provider.redis.quarkus.QuarkusRedisLockProvider Maven / Gradle / Ivy

package net.javacrumbs.shedlock.provider.redis.quarkus;

import static io.vertx.mutiny.redis.client.Command.SET;
import static net.javacrumbs.shedlock.support.Utils.getHostname;
import static net.javacrumbs.shedlock.support.Utils.toIsoString;

import io.quarkus.redis.datasource.RedisDataSource;
import io.quarkus.redis.datasource.keys.KeyCommands;
import io.vertx.mutiny.redis.client.Response;
import java.time.Duration;
import java.time.Instant;
import java.util.Optional;
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.SimpleLock;
import net.javacrumbs.shedlock.support.LockException;
import net.javacrumbs.shedlock.support.annotation.NonNull;

/**
 * Uses Redis's `SET resource-name anystring NX EX max-lock-ms-time` as locking
 * mechanism.
 *
 * 

* See Set command */ public class QuarkusRedisLockProvider implements ExtensibleLockProvider { private static final String KEY_PREFIX_DEFAULT = "job-lock"; private final RedisDataSource redisDataSource; private final KeyCommands keyCommands; private final String keyPrefix; public QuarkusRedisLockProvider(RedisDataSource dataSource) { this(dataSource, KEY_PREFIX_DEFAULT); } public QuarkusRedisLockProvider(@NonNull RedisDataSource dataSource, @NonNull String keyPrefix) { this.keyPrefix = keyPrefix; this.redisDataSource = dataSource; this.keyCommands = dataSource.key(String.class); } @Override @NonNull public Optional lock(@NonNull LockConfiguration lockConfiguration) { long expireTime = getMillisUntil(lockConfiguration.getLockAtMostUntil()); String key = buildKey(lockConfiguration.getName()); Response response = redisDataSource.execute(SET, key, buildValue(), "NX", "PX", Long.toString(expireTime)); if (response != null && "OK".equals(response.toString())) { return Optional.of(new RedisLock(key, this, lockConfiguration)); } else { return Optional.empty(); } } private Optional extend(LockConfiguration lockConfiguration) { long expireTime = getMillisUntil(lockConfiguration.getLockAtMostUntil()); String key = buildKey(lockConfiguration.getName()); boolean success = extendKeyExpiration(key, expireTime); if (success) { return Optional.of(new RedisLock(key, this, lockConfiguration)); } return Optional.empty(); } String buildKey(String lockName) { return keyPrefix + ":" + lockName; } private boolean extendKeyExpiration(String key, long expiration) { return keyCommands.pexpire(key, expiration); } private void deleteKey(String key) { keyCommands.del(key); } private static final class RedisLock extends AbstractSimpleLock { private final String key; private final QuarkusRedisLockProvider quarkusLockProvider; private RedisLock(String key, QuarkusRedisLockProvider jedisLockProvider, LockConfiguration lockConfiguration) { super(lockConfiguration); this.key = key; this.quarkusLockProvider = jedisLockProvider; } @Override public void doUnlock() { long keepLockFor = getMillisUntil(lockConfiguration.getLockAtLeastUntil()); // lock at least until is in the past if (keepLockFor <= 0) { try { quarkusLockProvider.deleteKey(key); } catch (Exception e) { throw new LockException("Can not remove key", e); } } else { quarkusLockProvider.extendKeyExpiration(key, keepLockFor); } } @Override @NonNull protected Optional doExtend(@NonNull LockConfiguration newConfiguration) { return quarkusLockProvider.extend(newConfiguration); } } private static long getMillisUntil(Instant instant) { return Duration.between(ClockProvider.now(), instant).toMillis(); } private static String buildValue() { return String.format("ADDED:%s@%s", toIsoString(ClockProvider.now()), getHostname()); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy