Sharing objects with all verticles instances

1.3k Views Asked by At

My application, an API server, is thought to be organized as follows:

  1. MainVerticle is called on startup and should create all necessary objects for the application to work. Mainly a mongoDB pool of connections (MongoClient.createShared(...)) and a global configuration object available instance-wide. It also starts the HTTP Listener, several instances of a HttpVerticle.

  2. HttpVerticle is in charge of receiving requests and, based the command xxx in the payload, execute the XxxHandler.handle(...) method.

  3. Most of the XxxHandler.handle(...) methods will need to access the database. In addition, some others will also deploy additional verticles with parameters from the global conf. For example LoginHandler.handle(...) will deploy a verticle to keep user state while he's connected and this verticle will be undeployed when the user logs out.

I can't figure out how to get the global configuration object while being in XxxHandler.handle(...) or in a "sub"-verticle. Same for the mongo client.

Q1: For configuration data, I tried to use SharedData. In `MainVerticle.start() I have:

LocalMap<String, String> lm = vertx.sharedData().getLocalMap("conf");
lm.put("var", "val");

and in `HttpVerticle.start() I have:

LocalMap<String, String> lm = vertx.sharedData().getLocalMap("conf");
log.debug("var={}", lm.get("var"));

but the log output is var=null.... What am I doing wrong ?

Q2: Besides this basic example with a <String, String> map type, what if the value is a mutable Object like JsonObject which actually is what I would need ?

Q3: Finally how to make the instance of the mongo client available to all verticles?

1

There are 1 best solutions below

1
On

Instead of getLocalMap() you should be using getClusterWideMap(). Then you should be able to operate on shared data accross the whole cluster and not just in one verticle.

Be aware that the shared operations are async and the code might look like (code in Groovy):

vertx.sharedData().getClusterWideMap( 'your-name' ){ AsyncResult<AsyncMap<String,String>> res ->
  if( res.succeeded() )
    res.result().put( 'var', 'val', { log.info "put succeeded: ${it.succeeded()}" } )
}

You should be able to use any Serializable objects in your map.