[JAVA-519] MongoDB's connection is not a effective connection to a MongDB server where new Mongo(serverAddressList) Created: 11/Feb/12  Updated: 19/Oct/16  Resolved: 15/May/12

Status: Closed
Project: Java Driver
Component/s: None
Affects Version/s: 2.6.5, 2.7.2
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: xfc Assignee: Jeffrey Yemin
Resolution: Won't Fix Votes: 0
Labels: check, connection, mongodb, start
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
is duplicated by JAVA-520 There is no way to chack master in ja... Closed

 Description   

Here is our code to start mongoDB:

for (String hostName : hostNames) {
            String tmp[] = hostName.split(":");
            ServerAddress addr = new ServerAddress(tmp[0], Integer.parseInt(tmp[1]));
            hosts.add(addr);
        }
        mongo = new Mongo(hosts);
        db = mongo.getDB(dbName);
        WriteConcern wc = WriteConcern.valueOf(writeConcernName);
        db.setWriteConcern(wc);
        if (this.slaveOk) {
            db.slaveOk();
}

I find that Mongo instance does not check master;

The code of checking master is in Upate class:

_mongo.getConnector().checkMaster(true, false);//the second argument is failIfNoMaster

The checkMaster method code is in DBTcpConnection:

void checkMaster( boolean force , boolean failIfNoMaster )
        throws MongoException {
        
        if ( _rsStatus != null ){
            if ( _masterPortPool == null || force ){
                ReplicaSetStatus.Node n = _rsStatus.ensureMaster();
                if ( n == null ){
                    if ( failIfNoMaster )
                        throw new MongoException( "can't find a master" );
                }
                else {
                    _set( n._addr );
                    maxBsonObjectSize = _rsStatus.getMaxBsonObjectSize();
                }
            }
        } else {
            // single server, may have to obtain max bson size
            if (maxBsonObjectSize == 0)
                    maxBsonObjectSize = fetchMaxBsonObjectSize();
        }
    }

So,there are two problem:

First is:if I want to check master in staring my web applcation,I just have no choice;

Second is: The Mongo object instance actually represents a pool of connections to the database,this thing is not any valuable if we don't check master;

I suggest that you can make checkMaster method publicly or get us a button is check master.



 Comments   
Comment by Jeffrey Yemin [ 15/May/12 ]

This is an edge case and the workaround is acceptable, so we're not going to make an API change for it.

Comment by xfc [ 16/Feb/12 ]

The server has a "ping" command that makes more sense to use than DB.getCollectionNames:

if (checkMaster) {
    CommandResult cr = mongo.getDB("admin").command(new BasicDBObject("ping", 1));
    if (!cr.ok()) {
       ...
    }
}

Re:
I think that It's the same as:

this.db.getCollectionNames();

because,we all just use its DBTCPConnector's checkMaster method.


We can add a helper function to make that less verbose, if it works for you.

Re:thank you~

Comment by Jeffrey Yemin [ 13/Feb/12 ]

The server has a "ping" command that makes more sense to use than DB.getCollectionNames:

if (checkMaster) {
    CommandResult cr = mongo.getDB("admin").command(new BasicDBObject("ping", 1));
    if (!cr.ok()) {
       ...
    }
}

We can add a helper function to make that less verbose, if it works for you.

Comment by xfc [ 12/Feb/12 ]

The Mongo constructor is currently designed not to actually connect to the server or to throw exceptions as those could happen during any operation later.

Can you give us a button to decide whether we need actually connection to the server.

We just want to check master in our starting web application.

A full client code example:

public class MongoDataSource {

private static Logger log = LoggerFactory.getLogger(MongoDataSource.class);
private DB db;
private String dbName;
private Mongo mongo;
private String writeConcernName;
private WriteConcern writeConcern;
private boolean slaveOk;
private Set<String> hostNames = new HashSet<String>();
private List<ServerAddress> hosts = new ArrayList<ServerAddress>();
private boolean checkMaster;

public MongoDataSource(String replicaHosts, String dbName, String writeConcernName, boolean slaveOk,boolean checkMaster){
String names[] = replicaHosts.split(",");
for (String name : names)

{ hostNames.add(name); }

this.dbName = dbName;
this.writeConcernName = writeConcernName;
this.slaveOk = slaveOk;
this.checkMaster=checkMaster;
}

public void init() throws UnknownHostException, MongoException {
for (String hostName : hostNames)

{ String tmp[] = hostName.split(":"); ServerAddress addr = new ServerAddress(tmp[0], Integer.parseInt(tmp[1])); hosts.add(addr); }

mongo = new Mongo(hosts);
db = mongo.getDB(dbName);
WriteConcern wc = WriteConcern.valueOf(writeConcernName);
db.setWriteConcern(wc);
if (this.slaveOk)

{ db.slaveOk(); }

if (checkMaster)

{ db.getCollectionNames(); }

}

public void destroy()

{ mongo.close(); }

}

configuration in spring xml file:
<bean id="mongods" class="com.alibaba.cep.ep.dao.impl.MongoDataSource" init-method="init" destroy-method="destroy">
<constructor-arg value="10.20.30.56:11112"></constructor-arg>
<constructor-arg value="db"></constructor-arg>
<constructor-arg value="SAFE"></constructor-arg>
<constructor-arg value="false"></constructor-arg>
<constructor-arg value="true"></constructor-arg>
</bean>

Comment by Scott Hernandez (Inactive) [ 11/Feb/12 ]

Can you post a full client code example with a note where you expect things to be different including the WriteConcern you are using?

The Mongo constructor is currently designed not to actually connect to the server or to throw exceptions as those could happen during any operation later.

Comment by xfc [ 11/Feb/12 ]

now,my way to resolve this problem:
if (checkMaster) {
db.getCollectionNames();
}

The sqequnce of invoking class:
db.getCollectionNames()
--->namespaces.__find(new BasicDBObject(), null, 0, 0, 0, getOptions());
--->Response res = _connector.call( _db , this , query , null , 2 );
--->checkMaster( false , !slaveOk );

Generated at Thu Feb 08 08:52:29 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.