Question

So, I'm trying to make a Mongo connection that remains persistent across several uses of the application (page accesses). I'm tired of all these connections building up during my testing, and I want to use proper procedure by having that single persistent connection. Best practices and all that.

Here's what I have:

web.xml

<listener>
    <listener-class>com.core.tools.MyServletContextListener</listener-class>
</listener>

com.core.tools.MyServletContextListener

public class MyServletContextListener implements ServletContextListener {
    private static Logger log = org.apache.log4j.Logger.getLogger(MyServletContextListener.class);
    public void contextInitialized( ServletContextEvent sce ){
        try {
            EntityManager.setupMongoClient(sce);
        } catch (UnknownHostException e) {
            log.error("Error setting up Servlet Context");
        }
    }

    public void contextDestroyed( ServletContextEvent sce ){
        EntityManager.closeMongoClient(sce);
    }
}

EntityManager

public class EntityManager {
    private static MongoClient      mongoConnection = null;
    private static Jongo            jongoDatasource = null;

    public static void setupMongoClient( ServletContextEvent sce ) throws UnknownHostException{
        if( sce.getServletContext().getAttribute("mongo") == null ){
            mongoConnection = new MongoClient("localhost");
            sce.getServletContext().setAttribute("mongo", mongoConnection );
        }else if (mongoConnection == null) {
            mongoConnection = (MongoClient) sce.getServletContext().getAttribute("mongo");
        }
    }

    public static Jongo getJongoDatasource(){
        if( jongoDatasource == null ){
            jongoDatasource = new Jongo(mongoConnection.getDB("coreTest"));
        }
        return jongoDatasource;
    }

    public static void closeMongoClient( ServletContextEvent sce ){
        if( sce.getServletContext().getAttribute("mongo") != null ){
            mongoConnection = (MongoClient) sce.getServletContext().getAttribute("mongo");
            mongoConnection.close();
        }
    }
}

What happens:

Good news - now my connections get cleaned up when the server closes.

Bad news - I still keep getting lots and lots of connections being created. Every time I hit the button, it makes a new connection ... but only for about 4 or 5 connections. Then it suddenly stops adding new connections for a while. Then it'll add 3 more. Then wait. Then another 2. Then nothing. Then a few minutes later, suddenly it'll add another 5 connections.

Confusing: I don't even know how it's managing to make those connections. Tracking the method calls - setupMongoClient is only called once - when the apache server starts up. It's the only place in the whole system that sets mongoConnection.

Whenever I press the button, mongoConnection is not set. And yet, the data is pulled from the mongo database, and testing mongoConnection shows me that it is not null.

How is mongoConnection not null? And why are new connections sporadically being made?

Was it helpful?

Solution

MongoClient is a connection pool; it maintains a number of open connections to the database for performance (creating new connection is costly).

when you call mongoConnection.getDB("DB"), MongoClient will retrieve a database connection from the connection pool. if there are no available connections in the connection pool, it will create a new connection and add it to the pool.

when you call mongoConnection.close(), the connection is not tear down. it is simply returned to the connection pool to be reused.

by default, the pool size is 5. this explains why you will eventually have 5 open connections even though you have closed them (remember, "closed" connections are returned to the pool). you can change this size

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top