skip to Main Content

I am new to Vertx and was exploring request-reply using event bus.

I want to implement below flow

  1. User requests for a data
  2. controller sends a message on event bus to a redis-processor verticle
  3. redis-processor will wait for n seconds till value is available in redis (there will be a background process which will keep on refreshing cache, hence the wait)
  4. redis-processor will send reply back to controller
  5. controller responds to user

In short I want to do something like this:

enter image description here

Now I want to implement this in Vertx since vertx can run asynchronously. Using event bus I can isolate controller from processor. So controller can accept multiple user request and stay responsive under load.
(I hope I am right with this!)

I have implemented this in very crude fashion in java-vertx. Stuck in below part.

//receive request from controller
vertx.eventBus().consumer(REQUEST_PROCESSOR, evtHandler -> {
    String txnId = evtHandler.body().toString();
    LOGGER.info("Received message:: {}", txnId);

    this.redisAPI.get(txnId, result -> {          // <=====
        String value = result.result().toString();
        LOGGER.info("Value in redis : {}", value);
        evtHandler.reply(value); // reply to controller
    });
}); 

pls see line denoted by arrow. How can I wait for x seconds without blocking event loop?

Please help.

2

Answers


  1. Thats actually very simple, you need a timer. Please see docs for details but you will need more or less something like this:

    vertx.setTimer(1000, id -> {
        this.redisAPI.get(txnId, result -> {          
            String value = result.result().toString();
            LOGGER.info("Value in redis : {}", value);
            evtHandler.reply(value); // reply to controller
        });
    });
    

    You might want to store the timer IDs somewhere so that you can cancel them or that at least you know something is running when a shutdown request comes in for your verticle to delay it. But this all depends on your needs.

    Login or Signup to reply.
  2. As @mohamnag said, you could use a Vertx timer

    here is another example on how to user timer.

    Note that the timer value is in ms.

    As an improvement to the, I will recommend checking that the callback has succeeded before attempting to get the value from redisAPI. This is done using the succeeded() method.
    In an asynchronous environment getting that result could fail due to several issues (network errors etc)

     vertx.setTimer(n * 1000, id -> {
        this.redisAPI.get(txnId, result -> {
          if(result.succeeded()){  // the callback succeeded to get a value from redis
            String value = result.result().toString();
            LOGGER.info("Value in redis : {}", value);
            evtHandler.reply(value); // reply to controller
          } else {
            LOGGER.error("Value could not be gotten from redis : {}", result.cause());
            evtHandler.fail(someIntegerCode, result.cause()); // reply with failure related info
          }
    
        });
      });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search