mirror of
https://github.com/pocoproject/poco.git
synced 2025-12-09 16:36:51 +01:00
enh(MongoDB): Add read-preference validation to replica set connection and pool.
This commit is contained in:
@@ -100,6 +100,12 @@ public:
|
||||
[[nodiscard]] bool isConnected() const;
|
||||
/// Returns true if currently connected to a server.
|
||||
|
||||
[[nodiscard]] bool matchesReadPreference() const;
|
||||
/// Returns true if the currently connected server still matches the read preference.
|
||||
/// Returns false if not connected or if the server no longer satisfies the read preference.
|
||||
/// This is useful for connection pool validation to detect when a server role has changed
|
||||
/// (e.g., primary became secondary).
|
||||
|
||||
private:
|
||||
void ensureConnection();
|
||||
/// Ensures we have an active connection, creating one if needed.
|
||||
|
||||
@@ -62,8 +62,10 @@ public:
|
||||
|
||||
bool validateObject(MongoDB::ReplicaSetConnection::Ptr pObject)
|
||||
{
|
||||
// Check if the connection is still valid
|
||||
return pObject->isConnected();
|
||||
// Check if the connection is still valid and matches the read preference.
|
||||
// This ensures that if a server changes role (e.g., primary becomes secondary),
|
||||
// the cached connection is invalidated and a new one is created.
|
||||
return pObject->isConnected() && pObject->matchesReadPreference();
|
||||
}
|
||||
|
||||
void activateObject(MongoDB::ReplicaSetConnection::Ptr pObject)
|
||||
|
||||
@@ -116,6 +116,42 @@ bool ReplicaSetConnection::isConnected() const
|
||||
}
|
||||
|
||||
|
||||
bool ReplicaSetConnection::matchesReadPreference() const
|
||||
{
|
||||
if (!isConnected())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the current topology
|
||||
TopologyDescription topology = _replicaSet.topology();
|
||||
|
||||
// Get the server description for the currently connected server
|
||||
ServerDescription server = topology.getServer(_connection->address());
|
||||
|
||||
// Check if the server is Unknown or has an error
|
||||
if (server.type() == ServerDescription::Unknown || server.hasError())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Use ReadPreference::selectServers to check if our current server
|
||||
// would be selected with the current read preference
|
||||
std::vector<ServerDescription> eligibleServers = _readPreference.selectServers(topology);
|
||||
|
||||
// Check if our current server is in the list of eligible servers
|
||||
for (const auto& eligible : eligibleServers)
|
||||
{
|
||||
if (eligible.address() == _connection->address())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void ReplicaSetConnection::ensureConnection()
|
||||
{
|
||||
if (_connection.isNull())
|
||||
|
||||
Reference in New Issue
Block a user