mszmurlo
mszmurlo

Reputation: 1339

Pattern for using properly MongoClient in Vert.x

I feel quite uncomfortable with the MongoClient class, certainly because I don't exactly understand what it is and how it works.

The first call to MongoClient.createShared will actually create the pool, and the specified config will be used.

Subsequent calls will return a new client instance that uses the same pool, so the configuration won’t be used.

Does that mean that the pattern should be:

  1. In startup function, to create the pool, we make a call

    mc = MongoClient.createShared(vx, config, "poolname");
    

    Is the returned value mc important for this first call if it succeeds? What is its value if the creation of the pool fails? The documentations doesn't say. There is a socket exception if mongod is not running, but what about the other cases?

  2. In another place in the code (another verticle, for example), can we write mc = MongoClient.createShared(vx, new JsonObject(), "poolname"); to avoid to systematically need to access shared objects.

  3. Again, In another verticle where we need to access the database, should we define MongoClient mc

    • as a class field in which case it will be released to the pool only in the stop() method, or
    • shouldn't it be a variable populated with MongoClient.createShared(...) and de-allocated with mc.close() once we don't need the connection any more in order release it again to the pool ?

What I would write is as follows

// Main startup Verticle
import ...

public class MainVerticle extends AbstractVerticle {
  ...      
  @Override
  public void start(Future<Void> sf) throws Exception {
     ...
     try {
       MongoClient.createShared(vx, config().getJsonObject("mgcnf"),  "pool");
     }
     catch(Exception e) {
       log.error("error error...");
       sf.fail("failure reason");
       return;
     }
     ...
     sf.complete();
  }
  ...some other methods
}

and then, in some other place

public class SomeVerticle extends AbstractVerticle {

    public void someMethod(...) {
    ...
    // use the database:
    MongoClient mc = MongoClient.createShared(vx,  new JsonObject(),  "pool");
        mc.save(the_coll, the_doc, res -> {
            mc.close();
            if(res.succeeded()) {
                ...
            }
            else {
                ...
            }   
       }
       ...
   }
   ...
}

Does that make sense ? Yet, this is not what is in the examples that I could find around the internet.

Upvotes: 0

Views: 168

Answers (1)

DoctorPangloss
DoctorPangloss

Reputation: 3073

Don't worry about pools. Don't use them. They don't do what you think they do.

In your start method of any verticle, set a field (what you call a class field, but you really mean instance field) on the inheritor of AbstractVerticle to MongoClient.createShared(getVertx(), config). Close the client in your stop method. That's it.

The other exceptions you'll see are:

  • Bad username/password
  • Unhealthy cluster state
  • The Java driver has a limit of 500 or 1,000 connections (depending on version), you'll receive an exception if you exceed this connection count

Both will be propagated up from the driver wrapped in a VertxException.

Upvotes: 1

Related Questions