PyMongo, why I can't sometimes get info about primary?

for project I need to check ability to write in replica. If I can’t, I do write only in log file, skipping MongoDB

I’m checking primary with MongoClinent()["dbname"].clinet.primary method. But It return often None. I don’t know why. Help me with undersyanding
Link on documentation - mongo_client – Tools for connecting to MongoDB - PyMongo 4.13.2 documentation

class Store:
     39   def __init__(self, hosts: List[str], port: int, replica_set: str, db_name: str) -> None:
     40     self.hosts = [f"{i}:{port}" for i in hosts]
     41     self.replica_set = replica_set
     42     self.db_name = db_name
     43 
     44   @property
     45   def db(self) -> Database:
     46     client = MongoClient(self.hosts, replicaset=self.replica_set, uuidRepresentation='standard', connect=True)
     47     return client[self.db_name]
     48 
     49 
     50 
     51 if __name__ == '__main__':
     52   global CONFIG
     53   CONFIG = Config("/etc/vpn.conf")
     54   
     55   store = Store(CONFIG.db.hosts, CONFIG.db.port, CONFIG.db.replica_set, CONFIG.db.db_name)
     56 
     57   print("replica name ")
     58   print(CONFIG.db.replica_set)
     59   print(store.db.client.nodes)
     60 
     61   print(store.db.client.primary)

MongoClient.primary does not block waiting to discover the primary so that behavior is expected (returning None when the client hasn’t yet discovered a primary). You should use MongoClient.is_primary instead. is_primary blocks for up to serverSelectionTimeoutMS and raises ServerSelectionTimeoutError if it can’t discover a writeable server (mongod or mongos) in time.

You can shorten the serverSelectionTimeoutMS via the pymongo.timeout() api:

with pymongo.timeout(5.0):  # timeout after 5 seconds
    try:
        writeable = client.is_primary
    except ServerSelectionTimeoutError:
        # This can happen if the network is down or the cluster 
        writeable = False

However a better application design is to attempt the writes as normal and then catch ServerSelectionTimeoutError and write to the log file. A ServerSelectionTimeoutError can happen during any operation, checking client.is_primary first doesn’t provide any guarantees about the subsequent operation.

See:

2 Likes

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.