Shedlock with Spring and Redis

Viewed 2907

I'm using Shedlock with Spring Boot and Redis as Lock Provider.

Everything seems to work fine. But when I manually go to the Redis during the execution of the task I see no specific KEY for the lock.

On the Redis CLI I do KEYS * to get all keys.

Is this expected or do I miss any configuration?

@Bean
public LockProvider lockProvider() {
   return new JedisLockProvider(redisPoolPrimary.getPool(), RedisPoolPrimary.ENV_ID);
}
@Component
@Slf4j
public class RedisPoolPrimary {

    public static final String ENV_ID = "MyAppId";
    private JedisPool pool;

    public RedisPoolPrimary(@Value("${spring.redis.url}") String redisCloudUrl,
                            @Value("${meetical.redis.jedis.JEDIS_POOL_MAX_TOTAL}") int jedisPoolMaxTotal,
                            @Value("${meetical.redis.jedis.JEDIS_POOL_MAX}") int jedisPoolMax,
                            @Value("${meetical.redis.jedis.JEDIS_POOLMAX_IDLE}") int jedisPoolMaxIdle
    ) {
        URI redisUrl = URI.create(redisCloudUrl);
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(jedisPoolMaxTotal);
        poolConfig.setMinIdle(jedisPoolMax);
        poolConfig.setMaxIdle(jedisPoolMaxIdle);
        pool = new JedisPool(poolConfig, redisUrl);
    }

    public JedisPool getPool() {
        return pool;
    }

}
@Scheduled(cron = "${cache.scheduler.cron.expression}")
@SchedulerLock(name = "refreshUserCachesLock", lockAtLeastForString = FIVE_MINUTES, lockAtMostForString = SIXTY_MINUTES)
public void refreshCacheOfAllInstances() {
   // should be only run once every x hours for all spring boot app nodes
   // however during execution of the task no KEY seems to be in Redis - does the lock mechanism work?
}

Dependencies used

        <dependency>
            <groupId>net.javacrumbs.shedlock</groupId>
            <artifactId>shedlock-spring</artifactId>
            <version>4.12.0</version>
        </dependency>
        <dependency>
            <groupId>net.javacrumbs.shedlock</groupId>
            <artifactId>shedlock-provider-redis-jedis</artifactId>
            <version>4.12.0</version>
        </dependency>
2 Answers

I haven't used jedis but the plain spring wrapper shedlock-provider-redis-spring. If your config works properly then you should be able to fetch by querying keys * with redis-cli. If not try forming the key manually and check in redis, shedlock uses below method in JedisLockProvider.java for forming a key that goes in redis.

 static String buildKey(String lockName, String env) {
        return String.format("%s:%s:%s", KEY_PREFIX, env, lockName);
    }

Check belowline in JedisLockProvider.java which actually maintains lock info in Redis.

https://github.com/lukas-krecan/ShedLock/blob/05d72cefa931634eaebabf2a7cdd400f1da416d7/providers/redis/shedlock-provider-redis-jedis/src/main/java/net/javacrumbs/shedlock/provider/redis/jedis/JedisLockProvider.java#L154

I believe once the scheduled job is executed, the key value is deleted in redis. You can create a breakpoint in Class RedisLockProvider, lock method.

    public Optional<SimpleLock> lock(@NonNull LockConfiguration lockConfiguration) {
        String key = buildKey(lockConfiguration.getName());
        Expiration expiration = getExpiration(lockConfiguration.getLockAtMostUntil());
        if (TRUE.equals(tryToSetExpiration(redisTemplate, key, expiration, SET_IF_ABSENT))) {
            return Optional.of(new RedisLock(key, redisTemplate, lockConfiguration));
        } else {
            return Optional.empty();
        }
    }

After this method returns, then check the redis to see if your key is there.

Related