]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Implement limit on number of connecting connections
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Thu, 30 Jan 2020 05:24:52 +0000 (00:24 -0500)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Thu, 30 Jan 2020 05:24:52 +0000 (00:24 -0500)
src/lib/server/trunk.c
src/lib/server/trunk.h

index 4c6c961b98ac4790a0c76709d50141ddfb04e7dd..fe4cbed3a28b16a5c936cda722c5f6495a58875c 100644 (file)
@@ -319,6 +319,7 @@ CONF_PARSER const fr_trunk_config[] = {
        { FR_CONF_OFFSET("start", FR_TYPE_UINT32, fr_trunk_conf_t, start), .dflt = "5" },
        { FR_CONF_OFFSET("min", FR_TYPE_UINT16, fr_trunk_conf_t, min), .dflt = "1" },
        { FR_CONF_OFFSET("max", FR_TYPE_UINT16, fr_trunk_conf_t, max), .dflt = "5" },
+       { FR_CONF_OFFSET("connecting", FR_TYPE_UINT16, fr_trunk_conf_t, connecting), .dflt = "2" },
        { FR_CONF_OFFSET("uses", FR_TYPE_UINT64, fr_trunk_conf_t, max_uses), .dflt = "0" },
        { FR_CONF_OFFSET("lifetime", FR_TYPE_TIME_DELTA, fr_trunk_conf_t, lifetime), .dflt = "0" },
 
@@ -3023,6 +3024,23 @@ static void trunk_manage(fr_trunk_t *trunk, fr_time_t now, char const *caller)
         *      spawn more connections!
         */
        if ((trunk->last_above_target >= trunk->last_below_target)) {
+               /*
+                *      If connecting is provided, check we
+                *      wouldn't have too many connections in
+                *      the connecting state.
+                *
+                *      This is a throttle in the case of transitory
+                *      load spikes, or a backend becoming
+                *      unavailable.
+                */
+               if ((trunk->conf.connecting > 0) &&
+                   (fr_trunk_connection_count_by_state(trunk, FR_CONNECTION_STATE_CONNECTING) >=
+                    trunk->conf.connecting)) {
+                       DEBUG4("Not opening connection - Too many (%u) connections in the connecting state",
+                              trunk->conf.connecting);
+                       return;
+               }
+
                if ((trunk->last_above_target + trunk->conf.open_delay) > now) {
                        DEBUG4("Not opening connection - Need to be above target for %pVs.  It's been %pVs",
                               fr_box_time_delta(trunk->conf.open_delay),
index 6f8afbfb5d239710162efc682695062176acb096..b41edd175c9658856aa86b0287813f172abe8356 100644 (file)
@@ -50,12 +50,16 @@ typedef struct {
 
        uint16_t                max;                    //!< Maximum number of connections in the trunk.
 
+       uint16_t                connecting;             //!< Maximum number of connections that can be in the
+                                                       ///< connecting state.  Used to throttle connection spawning.
+
        uint32_t                target_req_per_conn;    //!< How many pending requests should ideally be
                                                        ///< running on each connection.  Averaged across
                                                        ///< the 'active' set of connections.
 
        uint32_t                max_req_per_conn;       //!< Maximum connections per request.
-                                                       ///< Used to determine if we need to create new connections.
+                                                       ///< Used to determine if we need to create new connections
+                                                       ///< and whether we can enqueue new requests.
 
        uint64_t                max_uses;               //!< The maximum time a connection can be used.