Skip to content

Instantly share code, notes, and snippets.

@mhewedy
Last active January 13, 2024 16:56
Show Gist options
  • Select an option

  • Save mhewedy/d09cef74a614613be9709e38a2b5c5ae to your computer and use it in GitHub Desktop.

Select an option

Save mhewedy/d09cef74a614613be9709e38a2b5c5ae to your computer and use it in GitHub Desktop.
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import java.time.Duration;
import java.util.function.Supplier;
@Slf4j
public class Idempotent {
private static final String KEY_PREFIX = "idempotent-";
private static final Duration LOCK_TIMEOUT = Duration.ofMinutes(5);
private static RedisTemplate<String, Object> redisTemplate;
public static void run(String key, Runnable action) {
initRedisTemplate();
checkKeyExists(key);
writeKey(key);
try {
action.run();
} finally {
removeKey(key);
}
}
public static <T> T run(String key, Supplier<T> action) {
initRedisTemplate();
checkKeyExists(key);
writeKey(key);
try {
return action.get();
} finally {
removeKey(key);
}
}
@SuppressWarnings({"unchecked"})
private static void initRedisTemplate() {
if (redisTemplate == null) {
redisTemplate = AppContextUtil.getBean(RedisTemplate.class, String.class, Object.class);
}
}
private static void checkKeyExists(String key) {
boolean exists = redisTemplate.opsForValue().get(KEY_PREFIX + key) != null;
if (exists) {
throw new RuntimeException("operation_in_progress, key: "+ key);
}
}
private static void writeKey(String key) {
log.trace("write key: {}", key);
redisTemplate.opsForValue().set(KEY_PREFIX + key, "1", LOCK_TIMEOUT);
}
private static void removeKey(String key) {
log.trace("remove key: {}", key);
redisTemplate.opsForValue().getAndDelete(KEY_PREFIX + key);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment