[JAVA-991] Cannot determine actual ReplSetStatus from singleton MongoClient getReplicaSetStatus() Created: 04/Oct/13  Updated: 31/Jan/18  Resolved: 31/Jan/18

Status: Closed
Project: Java Driver
Component/s: API
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major - P3
Reporter: Bob Kuhar Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
duplicates JAVA-805 Make connection pool and connection s... Closed

 Description   

Our application is such that the majority of it can work whenever the Mongo ReplicaSet is operating without a PRIMARY. Recently I had a requirement to produce a HealthCheck service that reported the following states based upon the availability and capability of the Mongo ReplicaSet

ReadWrite: ReplSet is operating with a PRIMARY, GET services should 20x, PUT services should 20x
ReadOnly: ReplSet is operating with only SECONDARIES, GET services should 20x, PUT services should 503
DOWN: No members of the ReplSet can be reached, services should 503

I was surprised at how difficult it was to write this code with the 2.11.3 Java driver. The sticking point was that my application follows the http://docs.mongodb.org/ecosystem/tutorial/getting-started-with-java-driver/ convention of establishing a Singleton MongoClient. The ReplicaStatus object produced by this singleton provides no methods to assert the health of anything but the master (its toString(), however, does know this). This made it impossible to discriminate between ReadOnly and DOWN. I need the ReplicaSetStatus produced by the Singleton MongoClient to provide a direct way to interrogate the 3 states of the ReplSet as seen by the Application Server

{ReadWrite, ReadOnly, DOWN}

Here is my current ugly workaround. I am looking for a way to drive out the whole "freshClient" part.

@Override
public ReplSetStatus getReplSetStatus() {
ReplSetStatus rss = ReplSetStatus.DOWN;
MongoClient freshClient = null;
try {
if ( mongo != null ) {
ReplicaSetStatus replicaSetStatus = mongo.getReplicaSetStatus();
if ( replicaSetStatus != null ) {
if ( replicaSetStatus.getMaster() != null )

{ rss = ReplSetStatus.ReadWrite; }

else {
/*

  • When mongo.getReplicaSetStatus().getMaster() returns null, it takes a a
  • fresh client to assert whether the ReplSet is read-only or completely
  • down. What a hack.
    */
    freshClient = new MongoClient( mongo.getAllAddress(), mongo.getMongoClientOptions() );
    replicaSetStatus = freshClient.getReplicaSetStatus();
    if ( replicaSetStatus != null ) { rss = replicaSetStatus.getMaster() != null ? ReplSetStatus.ReadWrite : ReplSetStatus.ReadOnly; }

    else

    { log.warn( "freshClient.getReplicaSetStatus() is null" ); }

    }
    } else

    { log.warn( "mongo.getReplicaSetStatus() returned null" ); }

    } else

    { throw new IllegalStateException( "mongo is null?!?" ); }

    } catch ( Throwable t )

    { log.error( "Ingore unexpected error", t ); }

    finally

    Unknown macro: { if ( freshClient != null ) { freshClient.close(); } }

    log.debug( "getReplSetStatus(): {}", rss );
    return rss;
    }

Alternatively, if I could as the MongoClient "can you support this ReadPreference right now?" or "can you support this WriteConcern currently?" that would work too, or maybe even better.

/**

  • @return true if current state of Client can support readPreference, false otherwise
    */
    boolean canDoRead( ReadPreference readPreference );

/**

  • @return true if current state of Client can support writeConcern; false otherwise
    */
    boolean mongo.canDoWrite( WriteConcern writeConcern )


 Comments   
Comment by Jeffrey Yemin [ 31/Jan/18 ]

I don't see this as something we should address. Even though getReplicaSetStatus presents a simple, synchronous API, it's not flexible enough to handle the wide variety of possible interrogations of the current ClusterDescription. Since registering a ClusterListener in MongoClientOptions is also fairly straightforward, and allows applications to detect whatever state they are interested in, I'm closing this one as Won't Fix.

Comment by Bob Kuhar [ 04/Dec/13 ]

I can see how JAVA-805 would allow me to build a "what state is the
ReplSet in now" capability, but I would still like to be able to make a
single call to mongo.getReplicaSetStatus() and learn which of 3 states of
(DOWN, ReadOnly, ReadWrite) the ReplSet is in from my Singleton
MongoClient. I don't see that this is part of JAVA-805 directly. The
guiding principal should be mongo.getReplicaSetStatus() returns 1 of 3
states and is always current. Today, it does not, thus JAVA-991.

Thanks,
Bob

Comment by Jeffrey Yemin [ 04/Dec/13 ]

Hi Bob,

It looks like JAVA-805 will handle this use case. Do you agree?

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