I am storing a Cart in Redis using Spring Data Redis for a specific time. An expiration property annotated with @TimeToLive sets the time to live for the Cart object as described by the code below.
I have set KeyExpirationEventMessageListener
type to listen to the expiration event in order to process additional work at the expiration event. I was able to fetch the key from the triggered event of the expiration object and I am trying to access it or its phantom object at the expiry time using the spring data repository but with no result.It returns an empty object which means that the original obeject is likely been deleted. I don’t know if it is the proper way to do it.But, is there a way to fetch the expiry object at expiration or just before it gets deleted to process motre work?
@RedisHash("cart")
public class Cart implements Serializable {
@Id
@Indexed
private String id;
private long customerId;
private Set<CartLine> lines = new HashSet<>();
@TimeToLive
private long expiration;
}
public interface ShoppingCartRepository extends CrudRepository<Cart, String> {
}
@Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
private RedisTemplate<?, ?> redisTemplate;
private ShoppingCartRepository repository;
public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer,
RedisTemplate redisTemplate, ShoppingCartRepository repository) {
super(listenerContainer);
this.redisTemplate = redisTemplate;
this.repository = repository;
}
@Override
public void onMessage(Message message, byte[] pattern) {
String key = new String(message.getBody());
try {
String id = extractId(key);
Optional<ShoppingCart> cart = repository.findById(id);
} catch(Exception e) {
logger.info("something went wrong ====> " + e.getStackTrace());
}
}
private String extractId(String key){
String keyPrefix = ShoppingCart.class.getAnnotation(RedisHash.class).value();
return key.substring((keyPrefix + ":").length());
}
}
2
Answers
There was once a use case in my scenario, you can actually use RedisKeyExpiredEvent,
when a particular key in Redis expires. It can hold the value of the
expired key next to the key.
You can proceed with the following implementaion.
You can find the sample implementation at [1].
Example using Spring boot 2.3.4.RELEASE