You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
proxysql/include/ServerSelection.h

85 lines
2.9 KiB

/**
* @file ServerSelection.h
* @brief Pure server selection algorithm for unit testability.
*
* Extracted from get_random_MySrvC() in the HostGroups Manager.
* Uses a lightweight ServerCandidate struct instead of MySrvC to
* avoid connection pool dependencies.
*
* @see Phase 3.4 (GitHub issue #5492)
*/
#ifndef SERVER_SELECTION_H
#define SERVER_SELECTION_H
#include <cstdint>
/**
* @brief Server status values (mirrors MySerStatus enum).
*
* Redefined here to avoid pulling in proxysql_structs.h and its
* entire dependency chain.
*/
enum ServerSelectionStatus {
SERVER_ONLINE = 0,
SERVER_SHUNNED = 1,
SERVER_OFFLINE_SOFT = 2,
SERVER_OFFLINE_HARD = 3,
SERVER_SHUNNED_REPLICATION_LAG = 4
};
/**
* @brief Lightweight struct with decision-relevant server fields only.
*
* Avoids coupling to MySrvC which contains connection pool pointers,
* MySQL_Connection objects, and other heavy dependencies.
*/
struct ServerCandidate {
int index; ///< Caller-defined index (returned on selection).
int64_t weight; ///< Selection weight (0 = never selected).
ServerSelectionStatus status; ///< Current health status.
unsigned int current_connections; ///< Active connection count.
unsigned int max_connections; ///< Maximum allowed connections.
unsigned int current_latency_us; ///< Measured latency in microseconds.
unsigned int max_latency_us; ///< Maximum allowed latency (0 = no limit).
unsigned int current_repl_lag; ///< Measured replication lag in seconds.
unsigned int max_repl_lag; ///< Maximum allowed lag (0 = no limit).
};
/**
* @brief Check if a server candidate is eligible for selection.
*
* A candidate is eligible when:
* - status == SERVER_ONLINE
* - current_connections < max_connections
* - current_latency_us <= max_latency_us (or max_latency_us == 0)
* - current_repl_lag <= max_repl_lag (or max_repl_lag == 0)
*
* @note In production, max_latency_us == 0 on a per-server basis means
* "use the thread default max latency." This extraction treats 0
* as "no limit" for simplicity. Callers should resolve defaults
* before populating the ServerCandidate.
*
* @return true if the candidate is eligible.
*/
bool is_candidate_eligible(const ServerCandidate &candidate);
/**
* @brief Select a server from candidates using weighted random selection.
*
* Filters candidates by eligibility, then selects from eligible ones
* using weighted random with the provided seed for deterministic testing.
*
* @param candidates Array of server candidates.
* @param count Number of candidates in the array.
* @param random_seed Seed for deterministic random selection.
* @return Index field of the selected candidate, or -1 if none eligible.
*/
int select_server_from_candidates(
const ServerCandidate *candidates,
int count,
unsigned int random_seed
);
#endif // SERVER_SELECTION_H