<!-- JSON-LD markup generated by Google Structured Data Markup Helper. --><script type="application/ld+json">{  "@context" : "http://schema.org",  "@type" : "Article",  "name" : "Using Redis keyspace notifications for discard task after the timeout",  "author" : {    "@type" : "Person",    "name" : "Subham Majavadiya"  },  "image" : "https://global-uploads.webflow.com/5ef788f07804fb7d78a4127a/5f3272076e05504936ddad24_Using%20Redis%20keyspace%20notifications%20for%20discard%20task%20after%20the%20timeout.png",  "articleSection" : "how to implement some sort of timeout mechanism to discard any task if that task surpassed the maximum wait time",  "articleBody" : [ "Enable keyspace notifications for Expired key Only", "Enable Using Redis-CLI", "Enable Using Redis.conf", "Create Task timeout listener" ],  "url" : "https://www.engati.com/blog/using-redis-keyspace-notifications-for-discard-task-after-the-timeout",  "publisher" : {    "@type" : "Organization",    "name" : "Engati"  }}</script>

Tech Corner

How to discard tasks after timeouts with Redis keyspace notifications?

Engati Team
.
Dec 19
.
2-3 mins

Table of contents

Key takeawaysCollaboration platforms are essential to the new way of workingEmployees prefer engati over emailEmployees play a growing part in software purchasing decisionsThe future of work is collaborativeMethodology

I was trying to figure out how to implement some sort of timeout mechanism to discard any task if that task surpassed the maximum wait time, and the wait time can be configurable in seconds, minutes, hours, and may vary from customer to customer.

Then I came across notifications events in Redis. This article will give you an overview of how I have used Redis keyspace notifications events with the spring boot application to achieve the functionality.

Basically the idea here is whenever a new task came in, set a key in Redis with some prefix along with task metadata and expiry as the configured max wait time, and then by using Redis Keyspace Notifications for Expired Keys listen to the key expiry event, and based on that discard the task.

Enable keyspace notifications for Expired key Only:

IMPORTANT Keyspace notifications feature is available in Redis server version 2.8.0 or higher.

By default keyspace, notifications are disabled in Redis to avoid unnecessary CPU utilization. There are two ways we can enable this either using redis-cli or redis.conf file.

Enable Using Redis-CLI:

Subhams-MBP-2:~ subhammajavadiya$ redis-cli
127.0.0.1:6379> config set notify-keyspace-events Ex
OK

Enable Using Redis.conf:

By adding the below line in redis.conf and restarting the redis-server.

notify-keyspace-events Ex

I would recommend enabling from redis.conf file in the production environment to avoid the config reset if redis-server gets restarted.

Create Task timeout listener

  • To listen to the key expire event in spring boot application I have added spring.data.redis dependency in the build.gradleand implemented TaskTimeOutListener as MessageListener bean.

@Slf4j
@Component
public class TaskTimeOutListener implements MessageListener {  @Override
 public void onMessage(Message message, byte[] pattern) {
   String body = new String(message.getBody());
   String channel = new String(message.getChannel());log.info("Received task timeout event: {} for key: {}", body, channel);

   String expiredKey = channel.split(":")[1];
   //implemented logic to discard task
 }}

  • Register TaskTimeOutListener, MessageListener bean with RedisMessageListenerContainer to listen the key expiry event with a specific pattern i.e task_with_max_wait_time__*

@Slf4j
@Configuration
public class RedisConfiguration {  @Bean
 public RedisMessageListenerContainer redisMessageListenerContainer(
     RedisConnectionFactory connectionFactory,
     TaskTimeOutListener taskTimeoutListener) {
   RedisMessageListenerContainer listenerContainer = new RedisMessageListenerContainer();
   listenerContainer.setConnectionFactory(connectionFactory);
   listenerContainer.addMessageListener(maxWaitTimeExpiryListener,
       new PatternTopic("__key*__:task_with_max_wait_time__*"));
   listenerContainer.setErrorHandler(
       e ->log.error("Error in redisMessageListenerContainer", e));
   return listenerContainer;
 }
}

  • Let’s start the spring boot application and from redis-cli set a task with expiry time as 10 sec with key task_with_max_wait_time__1.

Subhams-MBP-2:~ subhammajavadiya$ redis-cli
127.0.0.1:6379> SETEX  task_with_max_wait_time__1  10  "test task"
OK

  • After 10 seconds

{"@timestamp":"2020-06-12T19:28:48.063+00:00","@version":1,"message":"Received task timeout event: expired, for key :task_with_max_wait_time__1","logger_name":"com.test.redislistener.TaskTimeOutListener",

"thread_name":"redisMessageListenerContainer-2","level":"INFO","level_value":20000,"app_name":"test-app","log_type":"app"}

And, it's up and running. Hope this helps you.

Share
Share

Engati Team

At the forefront for digital customer experience, Engati helps you reimagine the customer journey through engagement-first solutions, spanning automation and live chat.

Andy is the Co-Founder and CIO of SwissCognitive - The Global AI Hub. He’s also the President of the Swiss IT Leadership Forum.

Andy is a digital enterprise leader and is transforming business strategies keeping the best interests of shareholders, customers, and employees in mind.

Follow him for your daily dose of AI news and thoughts on using AI to improve your business.

Catch our interview with Andy on AI in daily life

Continue Reading