Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ValueOperation setIFAbsent with ttl not working. #2081

Closed
codeayra opened this issue Jun 11, 2021 · 7 comments
Closed

ValueOperation setIFAbsent with ttl not working. #2081

codeayra opened this issue Jun 11, 2021 · 7 comments
Labels
status: feedback-provided Feedback has been provided

Comments

@codeayra
Copy link

codeayra commented Jun 11, 2021

I am using RedisTemplate with LettuceConnection Factory(in spring boot) to set key in Redis with ttl ,
Key is getting Set in redis but its ttl not getting set.

when I try to set ttl using redis-cli , its getting set.

here is the code.
public Boolean setIfAbsent(String key, Object value, long timeout, TimeUnit unit) { Boolean isSuccess = Boolean.FALSE; String absoluteKey = generateAbsoluteKey(key); log.info("Setting key {} in redis..", absoluteKey); try { String sValue = objectMapper.writeValueAsString(value); redisTemplate.opsForValue() .setIfAbsent(absoluteKey, sValue, timeout, unit); } catch (Exception e) { log.error("Error in saving value to redis cache for key: " + absoluteKey, e); } return isSuccess; }

RedisConfiguration is like following

implementation group: 'org.springframework.data', name: 'spring-data-redis'

`@Bean
public LettuceConnectionFactory lettuceConnectionFactory() {
return new LettuceConnectionFactory(hostName, port);
}

@Bean
public RedisTemplate<String, String> redisTemplate() {
    RedisTemplate<String, String> redisTemplate = new RedisTemplate<String, String>();
    redisTemplate.setConnectionFactory(lettuceConnectionFactory());
    redisTemplate.setExposeConnection(true);
    redisTemplate.setKeySerializer(new StringRedisSerializer());
    redisTemplate.setValueSerializer(new StringRedisSerializer());
    return redisTemplate;
}`

There is no error on console.
I am using spring-data-redis-2.5.0-M5
redis version I have tried with 6.2 also 4.0 .

Please suggest.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jun 11, 2021
@christophstrobl
Copy link
Member

I checked DefaultValueOperationsIntegrationTests#testSetIfAbsentWithExpiration for Lettuce and everything seems to work as expected. Maybe you can provide a complete minimal sample (something that we can unzip or git clone, build, and deploy) that reproduces the problem.

@christophstrobl christophstrobl added status: waiting-for-feedback We need additional information before we can continue and removed status: waiting-for-triage An issue we've not yet triaged labels Jun 11, 2021
@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Jun 11, 2021
@codeayra
Copy link
Author

I got the problem,
What I am doing first calling setIfAbsent with ttl and its working after that I get the key update its value and calling setIfPresent without ttl and which might be clearing its ttl.

How can I update a key value without clearing its ttl ?

@christophstrobl
Copy link
Member

I see - there's ankeepTtl option on Expiration that allows to do this. But it is not present on ValueOperations so you'd have to call it something like the following on the template.

return execute(connection -> connection.set(rawKey, rawValue, Expiration.keepTtl(), SetOption.ifPresent()), true);

I created #2084 for that.

@codeayra
Copy link
Author

codeayra commented Jun 11, 2021

Got this this error

org.springframework.data.redis.RedisSystemException: Error in execution; nested exception is io.lettuce.core.RedisCommandExecutionException: ERR syntax error

code is

public void update(String key, Object value) {
String absoluteKey = generateAbsoluteKey(key);
String valueString = objectMapper.writeValueAsString(value);
try {
redisTemplate.execute(connection -> connection
.set(rawKey(absoluteKey), rawValue(valueString), Expiration.keepTtl(), RedisStringCommands.SetOption
.ifPresent()), true);

    } catch (Exception e) {
        log.error("Error in saving value to redis cache for key: " + absoluteKey, e);
    }
}

@SuppressWarnings("unchecked")
private byte[] rawKey(Object key) {

    if (keySerializer() == null && key instanceof byte[]) {
        return (byte[]) key;
    }

    return keySerializer().serialize(key);
}

@SuppressWarnings("unchecked")
private byte[] rawValue(Object value) {

    if (valueSerializer() == null && value instanceof byte[]) {
        return (byte[]) value;
    }

    return valueSerializer().serialize(value);
}

@SuppressWarnings("rawtypes")
private RedisSerializer keySerializer() {
    return redisTemplate.getKeySerializer();
}

@SuppressWarnings("rawtypes")
private RedisSerializer valueSerializer() {
    return redisTemplate.getValueSerializer();
}

@christophstrobl
Copy link
Member

KEEPTTL is available as off Redis 6.
Does lettuce tell you more than just ERR syntax error?

@codeayra
Copy link
Author

nothing..just this error.

@codeayra
Copy link
Author

its working finally with redis 6. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: feedback-provided Feedback has been provided
Projects
None yet
Development

No branches or pull requests

3 participants