Files
poco/MongoDB/include/Poco/MongoDB/TopologyDescription.h

159 lines
5.0 KiB
C++

//
// TopologyDescription.h
//
// Library: MongoDB
// Package: MongoDB
// Module: TopologyDescription
//
// Definition of the TopologyDescription class.
//
// Copyright (c) 2025, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef MongoDB_TopologyDescription_INCLUDED
#define MongoDB_TopologyDescription_INCLUDED
#include "Poco/MongoDB/MongoDB.h"
#include "Poco/MongoDB/ServerDescription.h"
#include "Poco/MongoDB/Document.h"
#include "Poco/Net/SocketAddress.h"
#include <vector>
#include <map>
#include <string>
#include <mutex>
namespace Poco {
namespace MongoDB {
class MongoDB_API TopologyDescription
/// Maintains the complete MongoDB replica set topology state.
///
/// This class tracks all known servers in a replica set and their
/// current state. It is updated based on 'hello' command responses
/// from MongoDB servers.
///
/// The topology type automatically transitions based on server
/// discovery:
/// - Unknown: Initial state, no servers contacted
/// - Single: Single standalone server
/// - ReplicaSetNoPrimary: Replica set without a primary
/// - ReplicaSetWithPrimary: Replica set with a primary
/// - Sharded: Sharded cluster (mongos routers)
///
/// THREAD SAFETY:
/// This class is thread-safe. All public methods use internal
/// synchronization to protect the topology state.
{
public:
enum TopologyType
/// MongoDB topology type enumeration
{
Unknown, /// Topology not yet determined
Single, /// Single server (standalone)
ReplicaSetNoPrimary, /// Replica set without primary
ReplicaSetWithPrimary, /// Replica set with primary
Sharded /// Sharded cluster
};
TopologyDescription();
/// Creates an empty topology description.
explicit TopologyDescription(const std::string& setName);
/// Creates a topology description for a replica set with the given name.
TopologyDescription(const TopologyDescription& other);
/// Copy constructor.
TopologyDescription(TopologyDescription&& other) noexcept;
/// Move constructor.
~TopologyDescription();
/// Destroys the TopologyDescription.
TopologyDescription& operator=(const TopologyDescription& other);
/// Assignment operator.
TopologyDescription& operator=(TopologyDescription&& other) noexcept;
/// Move assignment operator.
[[nodiscard]] TopologyType type() const;
/// Returns the current topology type.
[[nodiscard]] std::string setName() const;
/// Returns the replica set name, or empty string if not a replica set.
void setName(const std::string& name);
/// Sets the replica set name.
[[nodiscard]] std::vector<ServerDescription> servers() const;
/// Returns a copy of all server descriptions.
/// This is thread-safe but creates a copy.
[[nodiscard]] ServerDescription findPrimary() const;
/// Finds and returns the primary server.
/// Returns an Unknown server description if no primary exists.
[[nodiscard]] std::vector<ServerDescription> findSecondaries() const;
/// Finds and returns all secondary servers.
[[nodiscard]] bool hasPrimary() const;
/// Returns true if a primary server exists in the topology.
[[nodiscard]] bool hasServer(const Net::SocketAddress& address) const;
/// Returns true if the server with the given address is in the topology.
[[nodiscard]] ServerDescription getServer(const Net::SocketAddress& address) const;
/// Returns the server description for the given address.
/// Returns an Unknown server description if not found.
void updateServer(const Net::SocketAddress& address, const Document& helloResponse, Poco::Int64 rttMicros);
/// Updates a server's description from a 'hello' command response.
/// If the server doesn't exist in the topology, it is added.
/// This may also trigger topology type transitions.
void markServerUnknown(const Net::SocketAddress& address, const std::string& error = "");
/// Marks a server as Unknown (typically after an error).
/// This may trigger topology type transitions.
void addServer(const Net::SocketAddress& address);
/// Adds a server to the topology in Unknown state.
/// If the server already exists, this is a no-op.
void removeServer(const Net::SocketAddress& address);
/// Removes a server from the topology.
/// This may trigger topology type transitions.
void clear();
/// Removes all servers and resets to Unknown topology type.
[[nodiscard]] std::size_t serverCount() const;
/// Returns the number of servers in the topology.
private:
void updateTopologyType();
/// Updates the topology type based on current server states.
/// Must be called while holding the mutex.
void processNewHosts(const std::vector<Net::SocketAddress>& hosts);
/// Processes newly discovered hosts from a hello response.
/// Must be called while holding the mutex.
mutable std::mutex _mutex;
TopologyType _type{Unknown};
std::string _setName;
std::map<Net::SocketAddress, ServerDescription> _servers;
};
} } // namespace Poco::MongoDB
#endif // MongoDB_TopologyDescription_INCLUDED