The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Data Structures | Macros | Typedefs | Functions | Variables
trunk.c File Reference

A management API for bonding multiple connections together. More...

#include <freeradius-devel/server/trunk.h>
#include <freeradius-devel/server/connection.h>
#include <freeradius-devel/server/trigger.h>
#include <freeradius-devel/util/misc.h>
#include <freeradius-devel/util/syserror.h>
#include <freeradius-devel/util/table.h>
#include <freeradius-devel/util/minmax_heap.h>
#include <freeradius-devel/util/stdatomic.h>
+ Include dependency graph for trunk.c:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  trunk_connection_s
 Associates request queues with a connection. More...
 
struct  trunk_request_s
 Wraps a normal request. More...
 
struct  trunk_request_state_log_t
 Trace state machine changes for a particular request. More...
 
struct  trunk_s
 Main trunk management handle. More...
 
struct  trunk_watch_entry_s
 An entry in a trunk watch function list. More...
 

Macros

#define _TRUNK_PRIVATE   1
 
#define CALL_WATCHERS(_trunk, _state)
 Call the state change watch functions. More...
 
#define CONN_BAD_STATE_TRANSITION(_new)
 
#define CONN_REORDER(_tconn)
 Reorder the connections in the active heap. More...
 
#define CONN_STATE_TRANSITION(_new, _log)
 
#define CONN_TRIGGER(_state)
 
#define COUNT_BY_STATE(_state, _list)
 
#define DEQUEUE_ALL(_src_list, _state)
 
#define DO_CONNECTION_ALLOC(_tconn)
 Allocate a new connection. More...
 
#define DO_CONNECTION_NOTIFY(_tconn, _events)
 Change what events the connection should be notified about. More...
 
#define DO_REQUEST_CANCEL(_treq, _reason)
 Call the cancel callback if set. More...
 
#define DO_REQUEST_CANCEL_MUX(_tconn)
 Write one or more cancellation requests to a connection. More...
 
#define DO_REQUEST_COMPLETE(_treq)
 Call the complete callback (if set) More...
 
#define DO_REQUEST_CONN_RELEASE(_treq)
 Call the "conn_release" callback (if set) More...
 
#define DO_REQUEST_DEMUX(_tconn)
 Read one or more requests from a connection. More...
 
#define DO_REQUEST_FAIL(_treq, _prev_state)
 Call the fail callback (if set) More...
 
#define DO_REQUEST_FREE(_treq)
 Call the free callback (if set) More...
 
#define DO_REQUEST_MUX(_tconn)
 Write one or more requests to a connection. More...
 
#define IN_HANDLER(_trunk)   (((_trunk)->in_handler) != NULL)
 
#define IN_REQUEST_CANCEL_MUX(_trunk)   (((_trunk)->funcs.request_cancel_mux) && ((_trunk)->in_handler == (void *)(_trunk)->funcs.request_cancel_mux))
 
#define IN_REQUEST_DEMUX(_trunk)   (((_trunk)->funcs.request_demux) && ((_trunk)->in_handler == (void *)(_trunk)->funcs.request_demux))
 
#define IN_REQUEST_MUX(_trunk)   (((_trunk)->funcs.request_mux) && ((_trunk)->in_handler == (void *)(_trunk)->funcs.request_mux))
 
#define IO_FUNC_VERIFY(_func)    fr_fatal_assert_msg(trunk->funcs._func, "CONSISTENCY_CHECK_FAILED %s[%i}: " #_func " was NULL", file, line)
 
#define IS_PROCESSING(_tconn)   ((tconn)->pub.state & TRUNK_CONN_PROCESSING)
 
#define IS_SERVICEABLE(_tconn)   ((_tconn)->pub.state & TRUNK_CONN_SERVICEABLE)
 
#define LOG_PREFIX   trunk->log_prefix
 
#define OVER_MAX_CHECK   if (++count > max) return (count - 1)
 
#define RECONNECT_BY_STATE(_state, _list)
 
#define REQUEST_BAD_STATE_TRANSITION(_new)
 
#define REQUEST_EXTRACT_BACKLOG(_treq)
 Remove the current request from the backlog. More...
 
#define REQUEST_EXTRACT_CANCEL(_treq)   fr_dlist_remove(&tconn->cancel, treq)
 Remove the current request from the cancel list. More...
 
#define REQUEST_EXTRACT_CANCEL_PARTIAL(_treq)
 Remove the current request from the cancel_partial slot. More...
 
#define REQUEST_EXTRACT_CANCEL_SENT(_treq)   fr_dlist_remove(&tconn->cancel_sent, treq)
 Remove the current request from the cancel sent list. More...
 
#define REQUEST_EXTRACT_PARTIAL(_treq)
 Remove the current request from the partial slot. More...
 
#define REQUEST_EXTRACT_PENDING(_treq)
 Remove the current request from the pending list. More...
 
#define REQUEST_EXTRACT_REAPABLE(_treq)   fr_dlist_remove(&tconn->reapable, treq)
 Remove the current request from the reapable list. More...
 
#define REQUEST_EXTRACT_SENT(_treq)   fr_dlist_remove(&tconn->sent, treq)
 Remove the current request from the sent list. More...
 
#define REQUEST_STATE_TRANSITION(_new)
 Record a request state transition and log appropriate output. More...
 
#define REQUEST_TRIGGER(_state)
 
#define TCONN_DLIST_SEARCH(_dlist)
 
#define TCONN_DLIST_VERIFY(_dlist, _state)
 
#define TCONN_MINMAX_HEAP_SEARCH(_heap)
 
#define TCONN_MINMAX_HEAP_VERIFY(_heap, _state)
 
#define TCONN_TREQ_CHECKS(_treq, _state)
 
#define TREQ_DLIST_SEARCH(_dlist)
 
#define TREQ_DLIST_VERIFY(_dlist, _state)
 
#define TREQ_HEAP_SEARCH(_heap)
 
#define TREQ_HEAP_VERIFY(_heap, _state)
 
#define TREQ_OPTION_SEARCH(_option)
 
#define TREQ_OPTION_VERIFY(_option, _state)
 
#define TRUNK_REQUEST_STATE_LOG_MAX   20
 The maximum number of state logs to record per request. More...
 
#define TRUNK_STATE_TRANSITION(_new)
 
#define TRUNK_TCONN_CHECKS(_tconn, _state)
 

Typedefs

typedef struct trunk_connection_s trunk_connection_t
 
typedef struct trunk_request_s trunk_request_t
 
typedef struct trunk_s trunk_t
 
typedef struct trunk_watch_entry_s trunk_watch_entry_t
 An entry in a trunk watch function list. More...
 

Functions

static int _state_log_entry_free (trunk_request_state_log_t *slog)
 Used for sanity checks to ensure all log entries have been freed. More...
 
static int _trunk_connection_free (trunk_connection_t *tconn)
 Free a connection. More...
 
static void _trunk_connection_lifetime_expire (UNUSED fr_event_list_t *el, UNUSED fr_time_t now, void *uctx)
 Trigger a reconnection of the trunk connection. More...
 
static void _trunk_connection_on_closed (UNUSED connection_t *conn, UNUSED connection_state_t prev, UNUSED connection_state_t state, void *uctx)
 Connection failed after it was connected. More...
 
static void _trunk_connection_on_connected (UNUSED connection_t *conn, UNUSED connection_state_t prev, UNUSED connection_state_t state, void *uctx)
 Connection transitioned to the connected state. More...
 
static void _trunk_connection_on_connecting (UNUSED connection_t *conn, UNUSED connection_state_t prev, UNUSED connection_state_t state, void *uctx)
 Connection transitioned to the connecting state. More...
 
static void _trunk_connection_on_failed (connection_t *conn, connection_state_t prev, connection_state_t state, void *uctx)
 Connection failed. More...
 
static void _trunk_connection_on_halted (UNUSED connection_t *conn, UNUSED connection_state_t prev, UNUSED connection_state_t state, void *uctx)
 Connection transitioned to the halted state. More...
 
static void _trunk_connection_on_init (UNUSED connection_t *conn, UNUSED connection_state_t prev, UNUSED connection_state_t state, void *uctx)
 Connection transitioned to the the init state. More...
 
static void _trunk_connection_on_shutdown (UNUSED connection_t *conn, UNUSED connection_state_t prev, UNUSED connection_state_t state, void *uctx)
 Connection transitioned to the shutdown state. More...
 
static int8_t _trunk_connection_order_by_shortest_queue (void const *one, void const *two)
 Order connections by queue depth. More...
 
static int _trunk_free (trunk_t *trunk)
 Free a trunk, gracefully closing all connections. More...
 
static int _trunk_request_free (trunk_request_t *treq)
 Actually free the trunk request. More...
 
static int8_t _trunk_request_prioritise (void const *a, void const *b)
 Compare two protocol requests. More...
 
static void _trunk_timer (fr_event_list_t *el, fr_time_t now, void *uctx)
 Event to periodically call the connection management function. More...
 
trunk_watch_entry_ttrunk_add_watch (trunk_t *trunk, trunk_state_t state, trunk_watch_t watch, bool oneshot, void const *uctx)
 Add a watch entry to the trunk state list. More...
 
trunk_ttrunk_alloc (TALLOC_CTX *ctx, fr_event_list_t *el, trunk_io_funcs_t const *funcs, trunk_conf_t const *conf, char const *log_prefix, void const *uctx, bool delay_start)
 Allocate a new collection of connections. More...
 
static void trunk_backlog_drain (trunk_t *trunk)
 Drain the backlog of as many requests as possible. More...
 
static void trunk_connection_auto_full (trunk_connection_t *tconn)
 Automatically mark a connection as inactive. More...
 
static void trunk_connection_auto_unfull (trunk_connection_t *tconn)
 Automatically mark a connection as active or reconnect it. More...
 
void trunk_connection_callback_readable (UNUSED fr_event_list_t *el, UNUSED int fd, UNUSED int flags, void *uctx)
 Standard I/O read function. More...
 
void trunk_connection_callback_writable (UNUSED fr_event_list_t *el, UNUSED int fd, UNUSED int flags, void *uctx)
 Standard I/O write function. More...
 
static void trunk_connection_close_if_empty (trunk_t *trunk, fr_dlist_head_t *head)
 Close connections in a particular connection list if they have no requests associated with them. More...
 
uint16_t trunk_connection_count_by_state (trunk_t *trunk, int conn_state)
 Return the count number of connections in the specified states. More...
 
static void trunk_connection_enter_active (trunk_connection_t *tconn)
 Transition a connection back to the active state. More...
 
static void trunk_connection_enter_draining (trunk_connection_t *tconn)
 Transition a connection to the draining state. More...
 
static void trunk_connection_enter_draining_to_free (trunk_connection_t *tconn)
 Transition a connection to the draining-to-reconnect state. More...
 
static void trunk_connection_enter_full (trunk_connection_t *tconn)
 Transition a connection to the full state. More...
 
static void trunk_connection_enter_inactive (trunk_connection_t *tconn)
 Transition a connection to the inactive state. More...
 
static void trunk_connection_enter_inactive_draining (trunk_connection_t *tconn)
 Transition a connection to the inactive-draining state. More...
 
static void trunk_connection_event_update (trunk_connection_t *tconn)
 Update the registrations for I/O events we're interested in. More...
 
bool trunk_connection_in_state (trunk_connection_t *tconn, int state)
 Returns true if the trunk connection is in one of the specified states. More...
 
static bool trunk_connection_is_full (trunk_connection_t *tconn)
 Return whether a trunk connection should currently be considered full. More...
 
int trunk_connection_manage_schedule (trunk_t *trunk)
 Schedule a trunk management event for the next time the event loop is executed. More...
 
void trunk_connection_manage_start (trunk_t *trunk)
 Allow the trunk to open and close connections in response to load. More...
 
void trunk_connection_manage_stop (trunk_t *trunk)
 Stop the trunk from opening and closing connections in response to load. More...
 
int trunk_connection_pop_cancellation (trunk_request_t **treq_out, trunk_connection_t *tconn)
 Pop a cancellation request off a connection's cancellation queue. More...
 
int trunk_connection_pop_request (trunk_request_t **treq_out, trunk_connection_t *tconn)
 Pop a request off a connection's pending queue. More...
 
static void trunk_connection_readable (trunk_connection_t *tconn)
 A connection is readable. More...
 
static void trunk_connection_remove (trunk_connection_t *tconn)
 Remove a trunk connection from whichever list it's currently in. More...
 
static uint64_t trunk_connection_requests_dequeue (fr_dlist_head_t *out, trunk_connection_t *tconn, int states, uint64_t max)
 Shift requests in the specified states onto new connections. More...
 
uint64_t trunk_connection_requests_requeue (trunk_connection_t *tconn, int states, uint64_t max, bool fail_bound)
 Move requests off of a connection and requeue elsewhere. More...
 
static uint64_t trunk_connection_requests_requeue_priv (trunk_connection_t *tconn, int states, uint64_t max, bool fail_bound)
 Remove requests in specified states from a connection, attempting to distribute them to new connections. More...
 
bool trunk_connection_search (trunk_connection_t *tconn, void *ptr)
 
void trunk_connection_signal_active (trunk_connection_t *tconn)
 Signal a trunk connection is no longer full. More...
 
void trunk_connection_signal_inactive (trunk_connection_t *tconn)
 Signal a trunk connection cannot accept more requests. More...
 
void trunk_connection_signal_readable (trunk_connection_t *tconn)
 Signal that a trunk connection is readable. More...
 
void trunk_connection_signal_reconnect (trunk_connection_t *tconn, connection_reason_t reason)
 Signal a trunk connection is no longer viable. More...
 
void trunk_connection_signal_writable (trunk_connection_t *tconn)
 Signal that a trunk connection is writable. More...
 
static int trunk_connection_spawn (trunk_t *trunk, fr_time_t now)
 Attempt to spawn a new connection. More...
 
void trunk_connection_verify (char const *file, int line, trunk_connection_t *tconn)
 
static void trunk_connection_writable (trunk_connection_t *tconn)
 A connection is writable. More...
 
int trunk_del_watch (trunk_t *trunk, trunk_state_t state, trunk_watch_t watch)
 Remove a watch function from a trunk state list. More...
 
static void trunk_manage (trunk_t *trunk, fr_time_t now)
 Implements the algorithm we use to manage requests per connection levels. More...
 
static void trunk_rebalance (trunk_t *trunk)
 Rebalance connections across active trunk members when a new connection becomes active. More...
 
void trunk_reconnect (trunk_t *trunk, int states, connection_reason_t reason)
 Force the trunk to re-establish its connections. More...
 
trunk_request_ttrunk_request_alloc (trunk_t *trunk, request_t *request)
 (Pre-)Allocate a new trunk request More...
 
static trunk_enqueue_t trunk_request_check_enqueue (trunk_connection_t **tconn_out, trunk_t *trunk, request_t *request)
 Check to see if a trunk request can be enqueued. More...
 
uint32_t trunk_request_count_by_connection (trunk_connection_t const *tconn, int req_state)
 Return the count number of requests associated with a trunk connection. More...
 
uint64_t trunk_request_count_by_state (trunk_t *trunk, int conn_state, int req_state)
 Return a count of requests on a connection in a specific state. More...
 
trunk_enqueue_t trunk_request_enqueue (trunk_request_t **treq_out, trunk_t *trunk, request_t *request, void *preq, void *rctx)
 Enqueue a request that needs data written to the trunk. More...
 
static trunk_enqueue_t trunk_request_enqueue_existing (trunk_request_t *treq)
 Enqueue a request which has never been assigned to a connection or was previously cancelled. More...
 
trunk_enqueue_t trunk_request_enqueue_on_conn (trunk_request_t **treq_out, trunk_connection_t *tconn, request_t *request, void *preq, void *rctx, bool ignore_limits)
 Enqueue additional requests on a specific connection. More...
 
static void trunk_request_enter_backlog (trunk_request_t *treq, bool new)
 Transition a request to the backlog state, adding it to the backlog of the trunk. More...
 
static void trunk_request_enter_cancel (trunk_request_t *treq, trunk_cancel_reason_t reason)
 Transition a request to the cancel state, placing it in a connection's cancellation list. More...
 
static void trunk_request_enter_cancel_complete (trunk_request_t *treq)
 Cancellation was acked, the request is complete, free it. More...
 
static void trunk_request_enter_cancel_partial (trunk_request_t *treq)
 Transition a request to the cancel_partial state, placing it in a connection's cancel_partial slot. More...
 
static void trunk_request_enter_cancel_sent (trunk_request_t *treq)
 Transition a request to the cancel_sent state, placing it in a connection's cancel_sent list. More...
 
static void trunk_request_enter_complete (trunk_request_t *treq)
 Request completed successfully, inform the API client and free the request. More...
 
static void trunk_request_enter_failed (trunk_request_t *treq)
 Request failed, inform the API client and free the request. More...
 
static void trunk_request_enter_partial (trunk_request_t *treq)
 Transition a request to the partial state, indicating that is has been partially sent. More...
 
static void trunk_request_enter_pending (trunk_request_t *treq, trunk_connection_t *tconn, bool new)
 Transition a request to the pending state, adding it to the backlog of an active connection. More...
 
static void trunk_request_enter_reapable (trunk_request_t *treq)
 Transition a request to the reapable state, indicating that it's been sent in its entirety, but no response is expected. More...
 
static void trunk_request_enter_sent (trunk_request_t *treq)
 Transition a request to the sent state, indicating that it's been sent in its entirety. More...
 
static void trunk_request_enter_unassigned (trunk_request_t *treq)
 Transition a request to the unassigned state, in preparation for re-assignment. More...
 
void trunk_request_free (trunk_request_t **treq_to_free)
 If the trunk request is freed then update the target requests. More...
 
static void trunk_request_remove_from_conn (trunk_request_t *treq)
 Remove a request from all connection lists. More...
 
trunk_enqueue_t trunk_request_requeue (trunk_request_t *treq)
 Re-enqueue a request on the same connection. More...
 
bool trunk_request_search (trunk_request_t *treq, void *ptr)
 
void trunk_request_signal_cancel (trunk_request_t *treq)
 Cancel a trunk request. More...
 
void trunk_request_signal_cancel_complete (trunk_request_t *treq)
 Signal that a remote server acked our cancellation. More...
 
void trunk_request_signal_cancel_partial (trunk_request_t *treq)
 Signal a partial cancel write. More...
 
void trunk_request_signal_cancel_sent (trunk_request_t *treq)
 Signal that a remote server has been notified of the cancellation. More...
 
void trunk_request_signal_complete (trunk_request_t *treq)
 Signal that a trunk request is complete. More...
 
void trunk_request_signal_fail (trunk_request_t *treq)
 Signal that a trunk request failed. More...
 
void trunk_request_signal_partial (trunk_request_t *treq)
 Signal a partial write. More...
 
void trunk_request_signal_reapable (trunk_request_t *treq)
 Signal that the request was written to a connection successfully, but no response is expected. More...
 
void trunk_request_signal_sent (trunk_request_t *treq)
 Signal that the request was written to a connection successfully. More...
 
void trunk_request_state_log (fr_log_t const *log, fr_log_type_t log_type, char const *file, int line, trunk_request_t const *treq)
 
void trunk_request_state_log_entry_add (char const *function, int line, trunk_request_t *treq, trunk_request_state_t new)
 
void trunk_request_verify (char const *file, int line, trunk_request_t *treq)
 
static uint64_t trunk_requests_per_connection (uint16_t *conn_count_out, uint32_t *req_count_out, trunk_t *trunk, fr_time_t now, NDEBUG_UNUSED bool verify)
 Update timestamps for when we last had a transition from above target to below target or vice versa. More...
 
bool trunk_search (trunk_t *trunk, void *ptr)
 
int trunk_start (trunk_t *trunk)
 Start the trunk running. More...
 
void trunk_verify (char const *file, int line, trunk_t *trunk)
 Verify a trunk. More...
 
static void trunk_watch_call (trunk_t *trunk, fr_dlist_head_t *list, trunk_state_t state)
 Call a list of watch functions associated with a state. More...
 

Variables

static atomic_uint_fast64_t request_counter = ATOMIC_VAR_INIT(1)
 
static fr_table_num_ordered_t const trunk_cancellation_reasons []
 
static size_t trunk_cancellation_reasons_len = NUM_ELEMENTS(trunk_cancellation_reasons)
 
conf_parser_t const trunk_config []
 Config parser definitions to populate a trunk_conf_t. More...
 
static conf_parser_t const trunk_config_connection []
 
static conf_parser_t const trunk_config_request []
 
static fr_table_num_indexed_bit_pos_t const trunk_conn_trigger_names []
 Map connection states to trigger names. More...
 
static size_t trunk_conn_trigger_names_len = NUM_ELEMENTS(trunk_conn_trigger_names)
 
static fr_table_num_ordered_t const trunk_connection_events []
 
static size_t trunk_connection_events_len = NUM_ELEMENTS(trunk_connection_events)
 
static fr_table_num_ordered_t const trunk_connection_states []
 
static size_t trunk_connection_states_len = NUM_ELEMENTS(trunk_connection_states)
 
static fr_table_num_indexed_bit_pos_t const trunk_req_trigger_names []
 Map request states to trigger names. More...
 
static size_t trunk_req_trigger_names_len = NUM_ELEMENTS(trunk_req_trigger_names)
 
static fr_table_num_ordered_t const trunk_request_states []
 
static size_t trunk_request_states_len = NUM_ELEMENTS(trunk_request_states)
 
static fr_table_num_ordered_t const trunk_states []
 
static size_t trunk_states_len = NUM_ELEMENTS(trunk_states)
 

Detailed Description

A management API for bonding multiple connections together.

Id
4f25c4263264e6c288f49422d25a2d7e66e5bcaa
Id
1874ec2a4ff1b11470da74343ff0de5fdedfac01

Definition in file trunk.c.


Data Structure Documentation

◆ trunk_connection_s

struct trunk_connection_s

Associates request queues with a connection.

Trunk connection state machine
Trunk request state machine

Definition at line 131 of file trunk.c.

+ Collaboration diagram for trunk_connection_s:
Data Fields
fr_dlist_head_t cancel Requests in the cancel state.
trunk_request_t * cancel_partial Partially written cancellation request.
fr_dlist_head_t cancel_sent Sent cancellation request.
fr_dlist_t entry Used to track the connection in the connecting, full and failed lists.
trunk_connection_event_t events The current events we expect to be notified on.
fr_heap_index_t heap_id Used to track the connection in the connected heap.
fr_event_timer_t const * lifetime_ev Maximum time this connection can be open.
trunk_request_t * partial Partially written request.
fr_heap_t * pending Requests waiting to be sent.
struct trunk_connection_pub_s pub Public fields in the trunk connection.

This MUST be the first field in this structure.

fr_dlist_head_t reapable Idle request.
fr_dlist_head_t sent Sent request.
uint64_t sent_count The number of requests that have been sent using this connection.

◆ trunk_request_s

struct trunk_request_s

Wraps a normal request.

Definition at line 97 of file trunk.c.

+ Collaboration diagram for trunk_request_s:
Data Fields
bool bound_to_conn Fail the request if there's an attempt to re-enqueue it.
trunk_cancel_reason_t cancel_reason Why this request was cancelled.
fr_dlist_t entry Used to track the trunk request in the conn->sent or trunk->backlog request.
fr_heap_index_t heap_id Used to track the request conn->pending heap.
uint64_t id Trunk request ID.
fr_time_t last_freed Last time this request was freed.
fr_dlist_head_t log State change log.
struct trunk_request_pub_s pub Public fields in the trunk request.

This MUST be the first field in this structure.

bool sent Trunk request has been sent at least once.

Used so that re-queueing doesn't increase trunk sent count.

◆ trunk_request_state_log_t

struct trunk_request_state_log_t

Trace state machine changes for a particular request.

Definition at line 74 of file trunk.c.

+ Collaboration diagram for trunk_request_state_log_t:
Data Fields
fr_dlist_t entry Entry in the linked list.
trunk_request_state_t from What state we transitioned from.
char const * function State change occurred in.
int line Line change occurred on.
fr_dlist_head_t * log_head To allow the log entry to remove itself on free.
trunk_connection_t * tconn The request was associated with.

Pointer may now be invalid, do no de-reference.

uint64_t tconn_id If the treq was associated with a connection the connection ID.
trunk_connection_state_t tconn_state If the treq was associated with a connection the connection state at the time of the state transition.
trunk_request_state_t to What state we transitioned to.

◆ trunk_s

struct trunk_s

Main trunk management handle.

Definition at line 195 of file trunk.c.

+ Collaboration diagram for trunk_s:
Data Fields
fr_minmax_heap_t * active Connections which can service requests.
fr_heap_t * backlog The request backlog.

Requests we couldn't immediately assign to a connection.

fr_dlist_head_t closed Connections that have closed.

Either due to shutdown, reconnection or failure.

trunk_conf_t conf Trunk common configuration.
fr_dlist_head_t connecting Connections which are not yet in the open state.
fr_dlist_head_t draining Connections that will be freed once all their requests are complete, but can be reactivated.
fr_dlist_head_t draining_to_free Connections that will be freed once all their requests are complete.
fr_event_list_t * el Event list used by this trunk and the connection.
fr_dlist_head_t failed Connections that'll be reconnected shortly.
fr_dlist_head_t free_requests Requests in the unassigned state.

Waiting to be enqueued.

bool freeing Trunk is being freed, don't spawn new connections or re-enqueue.
fr_dlist_head_t full Connections which have too many outstanding requests.
trunk_io_funcs_t funcs I/O functions.
void * in_handler Which handler we're inside.
fr_dlist_head_t inactive Connections which have been signalled to be inactive by the API client.
fr_dlist_head_t inactive_draining Connections which have been signalled to be inactive by the API client, which the trunk manager is draining to close.
fr_dlist_head_t init Connections which have not yet started connecting.
uint64_t last_req_per_conn The last request to connection ratio we calculated.
fr_rate_limit_t limit_last_failure_log Rate limit on "Refusing to enqueue requests - No active conns".
fr_rate_limit_t limit_max_requests_alloc_log Rate limit on "Refusing to alloc requests - Limit of * requests reached".
char const * log_prefix What to prepend to messages.
fr_event_timer_t const * manage_ev Periodic connection management event.
bool managing_connections Whether the trunk is allowed to manage (open/close) connections.
trunk_watch_entry_t * next_watcher Watcher about to be run. Used to prevent nested watchers.
struct trunk_pub_s pub Public fields in the trunk connection.

This MUST be the first field in this structure.

bool started Has the trunk been started.
fr_dlist_head_t to_free Connections we're done with and will free on the next call to trunk_manage.

This prevents connections from being freed whilst we're inside callbacks.

void * uctx Uctx data to pass to alloc.
fr_dlist_head_t watch[TRUNK_STATE_MAX] To be called when trunk changes state.

◆ trunk_watch_entry_s

struct trunk_watch_entry_s

An entry in a trunk watch function list.

Definition at line 183 of file trunk.c.

+ Collaboration diagram for trunk_watch_entry_s:
Data Fields
bool enabled Whether the watch entry is enabled.
fr_dlist_t entry List entry.
trunk_watch_t func Function to call when a trunk enters.

the state this list belongs to

bool oneshot Remove the function after it's called once.
void * uctx User data to pass to the function.

Macro Definition Documentation

◆ _TRUNK_PRIVATE

#define _TRUNK_PRIVATE   1

Definition at line 36 of file trunk.c.

◆ CALL_WATCHERS

#define CALL_WATCHERS (   _trunk,
  _state 
)
Value:
do { \
if (fr_dlist_empty(&(_trunk)->watch[_state])) break; \
trunk_watch_call((_trunk), &(_trunk)->watch[_state], _state); \
} while(0)
static bool fr_dlist_empty(fr_dlist_head_t const *list_head)
Check whether a list has any items.
Definition: dlist.h:501

Call the state change watch functions.

Definition at line 811 of file trunk.c.

◆ CONN_BAD_STATE_TRANSITION

#define CONN_BAD_STATE_TRANSITION (   _new)
Value:
do { \
if (!fr_cond_assert_msg(0, "[%" PRIu64 "] Trunk connection invalid transition %s -> %s", \
tconn->pub.conn->id, \
fr_table_str_by_value(trunk_connection_states, tconn->pub.state, "<INVALID>"), \
} while (0)
while(1)
Definition: acutest.h:856
#define fr_cond_assert_msg(_x, _fmt,...)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
Definition: debug.h:156
return
Definition: module.c:174
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
Definition: table.h:772
static fr_table_num_ordered_t const trunk_connection_states[]
Definition: trunk.c:399

Definition at line 448 of file trunk.c.

◆ CONN_REORDER

#define CONN_REORDER (   _tconn)
Value:
do { \
int _ret; \
if ((fr_minmax_heap_num_elements((_tconn)->pub.trunk->active) == 1)) break; \
if (!fr_cond_assert((_tconn)->pub.state == TRUNK_CONN_ACTIVE)) break; \
_ret = fr_minmax_heap_extract((_tconn)->pub.trunk->active, (_tconn)); \
if (!fr_cond_assert_msg(_ret == 0, "Failed extracting conn from active heap: %s", fr_strerror())) break; \
fr_minmax_heap_insert((_tconn)->pub.trunk->active, (_tconn)); \
} while (0)
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
Definition: debug.h:139
if(rcode > 0)
Definition: fd_read.h:9
int fr_minmax_heap_insert(fr_minmax_heap_t *hp, void *data)
Definition: minmax_heap.c:424
unsigned int fr_minmax_heap_num_elements(fr_minmax_heap_t *hp)
Return the number of elements in the minmax heap.
Definition: minmax_heap.c:533
int fr_minmax_heap_extract(fr_minmax_heap_t *hp, void *data)
Definition: minmax_heap.c:486
break
Definition: rlm_securid.c:421
@ TRUNK_CONN_ACTIVE
Connection is connected and ready to service requests.
Definition: trunk.h:91
char const * fr_strerror(void)
Get the last library error.
Definition: strerror.c:554

Reorder the connections in the active heap.

fr_heap_extract will also error out if heap_id is bad - no need for assert

Definition at line 772 of file trunk.c.

◆ CONN_STATE_TRANSITION

#define CONN_STATE_TRANSITION (   _new,
  _log 
)
Value:
do { \
_log("[%" PRIu64 "] Trunk connection changed state %s -> %s", \
tconn->pub.conn->id, \
fr_table_str_by_value(trunk_connection_states, tconn->pub.state, "<INVALID>"), \
tconn->pub.state = _new; \
CONN_TRIGGER(_new); \
trunk_requests_per_connection(NULL, NULL, trunk, fr_time(), false); \
} while (0)
#define fr_time()
Allow us to arbitrarily manipulate time.
Definition: state_test.c:8

Definition at line 437 of file trunk.c.

◆ CONN_TRIGGER

#define CONN_TRIGGER (   _state)
Value:
do { \
if (trunk->pub.triggers) { \
"<INVALID>"), true, NULL); \
} \
} while (0)
unlang_interpret_t * unlang_interpret_get_thread_default(void)
Get the default interpreter for this thread.
Definition: interpret.c:1787
static fr_table_num_indexed_bit_pos_t const trunk_conn_trigger_names[]
Map connection states to trigger names.
Definition: trunk.c:378

Definition at line 429 of file trunk.c.

◆ COUNT_BY_STATE

#define COUNT_BY_STATE (   _state,
  _list 
)
Value:
do { \
if (conn_state & (_state)) { \
tconn = NULL; \
while ((tconn = fr_dlist_next(&trunk->_list, tconn))) { \
count += trunk_request_count_by_connection(tconn, req_state); \
} \
} \
} while (0)
static void * fr_dlist_next(fr_dlist_head_t const *list_head, void const *ptr)
Get the next item in a list.
Definition: dlist.h:555
uint32_t trunk_request_count_by_connection(trunk_connection_t const *tconn, int req_state)
Return the count number of requests associated with a trunk connection.
Definition: trunk.c:2867

◆ DEQUEUE_ALL

#define DEQUEUE_ALL (   _src_list,
  _state 
)
Value:
do { \
while ((treq = fr_dlist_head(_src_list))) { \
OVER_MAX_CHECK; \
fr_assert(treq->pub.state == (_state)); \
trunk_request_enter_unassigned(treq); \
fr_dlist_insert_tail(out, treq); \
} } while (0)
static void * fr_dlist_head(fr_dlist_head_t const *list_head)
Return the HEAD item of a list or NULL if the list is empty.
Definition: dlist.h:486
static size_t char ** out
Definition: value.h:997

◆ DO_CONNECTION_ALLOC

#define DO_CONNECTION_ALLOC (   _tconn)
Value:
do { \
void *_prev = trunk->in_handler; \
DEBUG3("Calling connection_alloc(tconn=%p, el=%p, conf=%p, log_prefix=\"%s\", uctx=%p)", \
(_tconn), \
(_tconn)->pub.trunk->el, \
(_tconn)->pub.trunk->conf.conn_conf, \
trunk->log_prefix, \
(_tconn)->pub.trunk->uctx); \
(_tconn)->pub.trunk->in_handler = (void *) (_tconn)->pub.trunk->funcs.connection_alloc; \
(_tconn)->pub.conn = trunk->funcs.connection_alloc((_tconn), (_tconn)->pub.trunk->el, (_tconn)->pub.trunk->conf.conn_conf, (_tconn)->pub.trunk->log_prefix, trunk->uctx); \
(_tconn)->pub.trunk->in_handler = _prev; \
if (!(_tconn)->pub.conn) { \
ERROR("Failed creating new connection"); \
talloc_free(tconn); \
return -1; \
} \
} while(0)

Allocate a new connection.

Definition at line 663 of file trunk.c.

◆ DO_CONNECTION_NOTIFY

#define DO_CONNECTION_NOTIFY (   _tconn,
  _events 
)
Value:
do { \
if ((_tconn)->pub.trunk->funcs.connection_notify) { \
void *_prev = (_tconn)->pub.trunk->in_handler; \
DEBUG3("[%" PRIu64 "] Calling connection_notify(tconn=%p, conn=%p, el=%p, events=%s, uctx=%p)", \
(_tconn)->pub.conn->id, \
(_tconn), \
(_tconn)->pub.conn, \
(_tconn)->pub.trunk->el, \
fr_table_str_by_value(trunk_connection_events, (_events), "<INVALID>"), \
(_tconn)->pub.trunk->uctx); \
(_tconn)->pub.trunk->in_handler = (void *)(_tconn)->pub.trunk->funcs.connection_notify; \
(_tconn)->pub.trunk->funcs.connection_notify((_tconn), (_tconn)->pub.conn, (_tconn)->pub.trunk->el, (_events), (_tconn)->pub.trunk->uctx); \
(_tconn)->pub.trunk->in_handler = _prev; \
} \
} while(0)
#define DEBUG3(_fmt,...)
Definition: log.h:266
static fr_table_num_ordered_t const trunk_connection_events[]
Definition: trunk.c:421

Change what events the connection should be notified about.

Definition at line 685 of file trunk.c.

◆ DO_REQUEST_CANCEL

#define DO_REQUEST_CANCEL (   _treq,
  _reason 
)
Value:
do { \
if ((_treq)->pub.trunk->funcs.request_cancel) { \
request_t *request = (_treq)->pub.request; \
void *_prev = (_treq)->pub.trunk->in_handler; \
(_treq)->pub.trunk->in_handler = (void *)(_treq)->pub.trunk->funcs.request_cancel; \
ROPTIONAL(RDEBUG3, DEBUG3, "Calling request_cancel(conn=%p, preq=%p, reason=%s, uctx=%p)", \
(_treq)->pub.tconn->pub.conn, \
(_treq)->pub.preq, \
(_reason), \
"<INVALID>"), \
(_treq)->pub.trunk->uctx); \
(_treq)->pub.trunk->funcs.request_cancel((_treq)->pub.tconn->pub.conn, (_treq)->pub.preq, (_reason), (_treq)->pub.trunk->uctx); \
(_treq)->pub.trunk->in_handler = _prev; \
} \
} while(0)
#define ROPTIONAL(_l_request, _l_global, _fmt,...)
Use different logging functions depending on whether request is NULL or not.
Definition: log.h:528
#define RDEBUG3(fmt,...)
Definition: log.h:343
static fr_table_num_ordered_t const trunk_cancellation_reasons[]
Definition: trunk.c:413

Call the cancel callback if set.

Definition at line 516 of file trunk.c.

◆ DO_REQUEST_CANCEL_MUX

#define DO_REQUEST_CANCEL_MUX (   _tconn)
Value:
do { \
if ((_tconn)->pub.trunk->funcs.request_cancel_mux) { \
void *_prev = (_tconn)->pub.trunk->in_handler; \
DEBUG3("[%" PRIu64 "] Calling request_cancel_mux(tconn=%p, conn=%p, uctx=%p)", \
(_tconn)->pub.conn->id, \
(_tconn), \
(_tconn)->pub.conn, \
(_tconn)->pub.trunk->uctx); \
(_tconn)->pub.trunk->in_handler = (void *)(_tconn)->pub.trunk->funcs.request_cancel_mux; \
(_tconn)->pub.trunk->funcs.request_cancel_mux((_tconn)->pub.trunk->el, (_tconn), (_tconn)->pub.conn, (_tconn)->pub.trunk->uctx); \
(_tconn)->pub.trunk->in_handler = _prev; \
} \
} while(0)

Write one or more cancellation requests to a connection.

Definition at line 645 of file trunk.c.

◆ DO_REQUEST_COMPLETE

#define DO_REQUEST_COMPLETE (   _treq)
Value:
do { \
if ((_treq)->pub.trunk->funcs.request_complete) { \
request_t *request = (_treq)->pub.request; \
void *_prev = (_treq)->pub.trunk->in_handler; \
ROPTIONAL(RDEBUG3, DEBUG3, "Calling request_complete(request=%p, preq=%p, rctx=%p, uctx=%p)", \
(_treq)->pub.request, \
(_treq)->pub.preq, \
(_treq)->pub.rctx, \
(_treq)->pub.trunk->uctx); \
(_treq)->pub.trunk->in_handler = (void *)(_treq)->pub.trunk->funcs.request_complete; \
(_treq)->pub.trunk->funcs.request_complete((_treq)->pub.request, (_treq)->pub.preq, (_treq)->pub.rctx, (_treq)->pub.trunk->uctx); \
(_treq)->pub.trunk->in_handler = _prev; \
} \
} while(0)

Call the complete callback (if set)

Definition at line 555 of file trunk.c.

◆ DO_REQUEST_CONN_RELEASE

#define DO_REQUEST_CONN_RELEASE (   _treq)
Value:
do { \
if ((_treq)->pub.trunk->funcs.request_conn_release) { \
request_t *request = (_treq)->pub.request; \
void *_prev = (_treq)->pub.trunk->in_handler; \
(_treq)->pub.trunk->in_handler = (void *)(_treq)->pub.trunk->funcs.request_conn_release; \
ROPTIONAL(RDEBUG3, DEBUG3, "Calling request_conn_release(conn=%p, preq=%p, uctx=%p)", \
(_treq)->pub.tconn->pub.conn, \
(_treq)->pub.preq, \
(_treq)->pub.trunk->uctx); \
(_treq)->pub.trunk->funcs.request_conn_release((_treq)->pub.tconn->pub.conn, (_treq)->pub.preq, (_treq)->pub.trunk->uctx); \
(_treq)->pub.trunk->in_handler = _prev; \
} \
} while(0)

Call the "conn_release" callback (if set)

Definition at line 537 of file trunk.c.

◆ DO_REQUEST_DEMUX

#define DO_REQUEST_DEMUX (   _tconn)
Value:
do { \
void *_prev = (_tconn)->pub.trunk->in_handler; \
DEBUG3("[%" PRIu64 "] Calling request_demux(tconn=%p, conn=%p, uctx=%p)", \
(_tconn)->pub.conn->id, \
(_tconn), \
(_tconn)->pub.conn, \
(_tconn)->pub.trunk->uctx); \
(_tconn)->pub.trunk->in_handler = (void *)(_tconn)->pub.trunk->funcs.request_demux; \
(_tconn)->pub.trunk->funcs.request_demux((_tconn)->pub.trunk->el, (_tconn), (_tconn)->pub.conn, (_tconn)->pub.trunk->uctx); \
(_tconn)->pub.trunk->in_handler = _prev; \
} while(0)

Read one or more requests from a connection.

Definition at line 629 of file trunk.c.

◆ DO_REQUEST_FAIL

#define DO_REQUEST_FAIL (   _treq,
  _prev_state 
)
Value:
do { \
if ((_treq)->pub.trunk->funcs.request_fail) { \
request_t *request = (_treq)->pub.request; \
void *_prev = (_treq)->pub.trunk->in_handler; \
ROPTIONAL(RDEBUG3, DEBUG3, "Calling request_fail(request=%p, preq=%p, rctx=%p, state=%s uctx=%p)", \
(_treq)->pub.request, \
(_treq)->pub.preq, \
(_treq)->pub.rctx, \
fr_table_str_by_value(trunk_request_states, (_prev_state), "<INVALID>"), \
(_treq)->pub.trunk->uctx); \
(_treq)->pub.trunk->in_handler = (void *)(_treq)->pub.trunk->funcs.request_fail; \
(_treq)->pub.trunk->funcs.request_fail((_treq)->pub.request, (_treq)->pub.preq, (_treq)->pub.rctx, _prev_state, (_treq)->pub.trunk->uctx); \
(_treq)->pub.trunk->in_handler = _prev; \
} \
} while(0)
static fr_table_num_ordered_t const trunk_request_states[]
Definition: trunk.c:357

Call the fail callback (if set)

Definition at line 574 of file trunk.c.

◆ DO_REQUEST_FREE

#define DO_REQUEST_FREE (   _treq)
Value:
do { \
if ((_treq)->pub.trunk->funcs.request_free) { \
request_t *request = (_treq)->pub.request; \
void *_prev = (_treq)->pub.trunk->in_handler; \
ROPTIONAL(RDEBUG3, DEBUG3, "Calling request_free(request=%p, preq=%p, uctx=%p)", \
(_treq)->pub.request, \
(_treq)->pub.preq, \
(_treq)->pub.trunk->uctx); \
(_treq)->pub.trunk->in_handler = (void *)(_treq)->pub.trunk->funcs.request_free; \
(_treq)->pub.trunk->funcs.request_free((_treq)->pub.request, (_treq)->pub.preq, (_treq)->pub.trunk->uctx); \
(_treq)->pub.trunk->in_handler = _prev; \
} \
} while(0)

Call the free callback (if set)

Definition at line 594 of file trunk.c.

◆ DO_REQUEST_MUX

#define DO_REQUEST_MUX (   _tconn)
Value:
do { \
void *_prev = (_tconn)->pub.trunk->in_handler; \
DEBUG3("[%" PRIu64 "] Calling request_mux(el=%p, tconn=%p, conn=%p, uctx=%p)", \
(_tconn)->pub.conn->id, \
(_tconn)->pub.trunk->el, \
(_tconn), \
(_tconn)->pub.conn, \
(_tconn)->pub.trunk->uctx); \
(_tconn)->pub.trunk->in_handler = (void *)(_tconn)->pub.trunk->funcs.request_mux; \
(_tconn)->pub.trunk->funcs.request_mux((_tconn)->pub.trunk->el, (_tconn), (_tconn)->pub.conn, (_tconn)->pub.trunk->uctx); \
(_tconn)->pub.trunk->in_handler = _prev; \
} while(0)

Write one or more requests to a connection.

Definition at line 612 of file trunk.c.

◆ IN_HANDLER

#define IN_HANDLER (   _trunk)    (((_trunk)->in_handler) != NULL)

Definition at line 702 of file trunk.c.

◆ IN_REQUEST_CANCEL_MUX

#define IN_REQUEST_CANCEL_MUX (   _trunk)    (((_trunk)->funcs.request_cancel_mux) && ((_trunk)->in_handler == (void *)(_trunk)->funcs.request_cancel_mux))

Definition at line 705 of file trunk.c.

◆ IN_REQUEST_DEMUX

#define IN_REQUEST_DEMUX (   _trunk)    (((_trunk)->funcs.request_demux) && ((_trunk)->in_handler == (void *)(_trunk)->funcs.request_demux))

Definition at line 704 of file trunk.c.

◆ IN_REQUEST_MUX

#define IN_REQUEST_MUX (   _trunk)    (((_trunk)->funcs.request_mux) && ((_trunk)->in_handler == (void *)(_trunk)->funcs.request_mux))

Definition at line 703 of file trunk.c.

◆ IO_FUNC_VERIFY

#define IO_FUNC_VERIFY (   _func)     fr_fatal_assert_msg(trunk->funcs._func, "CONSISTENCY_CHECK_FAILED %s[%i}: " #_func " was NULL", file, line)

◆ IS_PROCESSING

#define IS_PROCESSING (   _tconn)    ((tconn)->pub.state & TRUNK_CONN_PROCESSING)

Definition at line 708 of file trunk.c.

◆ IS_SERVICEABLE

#define IS_SERVICEABLE (   _tconn)    ((_tconn)->pub.state & TRUNK_CONN_SERVICEABLE)

Definition at line 707 of file trunk.c.

◆ LOG_PREFIX

#define LOG_PREFIX   trunk->log_prefix

Definition at line 27 of file trunk.c.

◆ OVER_MAX_CHECK

#define OVER_MAX_CHECK   if (++count > max) return (count - 1)

◆ RECONNECT_BY_STATE

#define RECONNECT_BY_STATE (   _state,
  _list 
)
Value:
do { \
if (states & (_state)) { \
size_t i; \
for (i = fr_dlist_num_elements(&trunk->_list); i > 0; i--) { \
connection_signal_reconnect(((trunk_connection_t *)fr_dlist_tail(&trunk->_list))->pub.conn, reason); \
} \
} \
} while (0)
static unsigned int fr_dlist_num_elements(fr_dlist_head_t const *head)
Return the number of elements in the dlist.
Definition: dlist.h:939
static void * fr_dlist_tail(fr_dlist_head_t const *list_head)
Return the TAIL item of a list or NULL if the list is empty.
Definition: dlist.h:531
Associates request queues with a connection.
Definition: trunk.c:131

◆ REQUEST_BAD_STATE_TRANSITION

#define REQUEST_BAD_STATE_TRANSITION (   _new)
Value:
do { \
trunk_request_state_log(&default_log, L_ERR, __FILE__, __LINE__, treq); \
if (!fr_cond_assert_msg(0, "Trunk request %" PRIu64 " invalid transition %s -> %s", \
treq->id, \
fr_table_str_by_value(trunk_request_states, treq->pub.state, "<INVALID>"), \
} while (0)
fr_log_t default_log
Definition: log.c:291
@ L_ERR
Error message.
Definition: log.h:56

Definition at line 482 of file trunk.c.

◆ REQUEST_EXTRACT_BACKLOG

#define REQUEST_EXTRACT_BACKLOG (   _treq)
Value:
do { \
int _ret; \
_ret = fr_heap_extract(&(_treq)->pub.trunk->backlog, _treq); \
if (!fr_cond_assert_msg(_ret == 0, "Failed extracting conn from backlog heap: %s", fr_strerror())) break; \
} while (0)
int fr_heap_extract(fr_heap_t **hp, void *data)
Remove a node from the heap.
Definition: heap.c:239

Remove the current request from the backlog.

Definition at line 713 of file trunk.c.

◆ REQUEST_EXTRACT_CANCEL

#define REQUEST_EXTRACT_CANCEL (   _treq)    fr_dlist_remove(&tconn->cancel, treq)

Remove the current request from the cancel list.

Definition at line 752 of file trunk.c.

◆ REQUEST_EXTRACT_CANCEL_PARTIAL

#define REQUEST_EXTRACT_CANCEL_PARTIAL (   _treq)
Value:
do { \
fr_assert((_treq)->pub.tconn->cancel_partial == treq); \
tconn->cancel_partial = NULL; \
} while (0)

Remove the current request from the cancel_partial slot.

Definition at line 757 of file trunk.c.

◆ REQUEST_EXTRACT_CANCEL_SENT

#define REQUEST_EXTRACT_CANCEL_SENT (   _treq)    fr_dlist_remove(&tconn->cancel_sent, treq)

Remove the current request from the cancel sent list.

Definition at line 766 of file trunk.c.

◆ REQUEST_EXTRACT_PARTIAL

#define REQUEST_EXTRACT_PARTIAL (   _treq)
Value:
do { \
fr_assert((_treq)->pub.tconn->partial == treq); \
tconn->partial = NULL; \
} while (0)

Remove the current request from the partial slot.

Definition at line 733 of file trunk.c.

◆ REQUEST_EXTRACT_PENDING

#define REQUEST_EXTRACT_PENDING (   _treq)
Value:
do { \
int _ret; \
_ret = fr_heap_extract(&(_treq)->pub.tconn->pending, _treq); \
if (!fr_cond_assert_msg(_ret == 0, "Failed extracting conn from pending heap: %s", fr_strerror())) break; \
} while (0)

Remove the current request from the pending list.

Definition at line 723 of file trunk.c.

◆ REQUEST_EXTRACT_REAPABLE

#define REQUEST_EXTRACT_REAPABLE (   _treq)    fr_dlist_remove(&tconn->reapable, treq)

Remove the current request from the reapable list.

Definition at line 747 of file trunk.c.

◆ REQUEST_EXTRACT_SENT

#define REQUEST_EXTRACT_SENT (   _treq)    fr_dlist_remove(&tconn->sent, treq)

Remove the current request from the sent list.

Definition at line 742 of file trunk.c.

◆ REQUEST_STATE_TRANSITION

#define REQUEST_STATE_TRANSITION (   _new)
Value:
do { \
request_t *request = treq->pub.request; \
ROPTIONAL(RDEBUG3, DEBUG3, "Trunk request %" PRIu64 " changed state %s -> %s", \
treq->id, \
fr_table_str_by_value(trunk_request_states, treq->pub.state, "<INVALID>"), \
trunk_request_state_log_entry_add(__FUNCTION__, __LINE__, treq, _new); \
treq->pub.state = _new; \
REQUEST_TRIGGER(_new); \
} while (0)

Record a request state transition and log appropriate output.

Definition at line 471 of file trunk.c.

◆ REQUEST_TRIGGER

#define REQUEST_TRIGGER (   _state)
Value:
do { \
if (trunk->pub.triggers) { \
"<INVALID>"), true, NULL); \
} \
} while (0)
static fr_table_num_indexed_bit_pos_t const trunk_req_trigger_names[]
Map request states to trigger names.
Definition: trunk.c:339

Definition at line 460 of file trunk.c.

◆ TCONN_DLIST_SEARCH

#define TCONN_DLIST_SEARCH (   _dlist)
Value:
do { \
fr_dlist_foreach(&(trunk->_dlist), trunk_connection_t, tconn) { \
if (ptr == tconn) { \
fr_fprintf(stderr, "trunk_search: tconn %p on " #_dlist "\n", ptr); \
return true; \
} \
if (trunk_connection_search(tconn, ptr)) { \
fr_fprintf(stderr, " in tconn %p on " #_dlist "\n", tconn); \
return true; \
} \
} \
} while (0)
bool trunk_connection_search(trunk_connection_t *tconn, void *ptr)
Definition: trunk.c:5143

◆ TCONN_DLIST_VERIFY

#define TCONN_DLIST_VERIFY (   _dlist,
  _state 
)
Value:
do { \
_fr_dlist_verify(file, line, &(trunk->_dlist)); \
fr_dlist_foreach(&(trunk->_dlist), trunk_connection_t, tconn) { \
trunk_connection_verify(file, line, tconn); \
TRUNK_TCONN_CHECKS(tconn, _state); \
} \
} while (0)
int const char * file
Definition: acutest.h:702
int const char int line
Definition: acutest.h:702

◆ TCONN_MINMAX_HEAP_SEARCH

#define TCONN_MINMAX_HEAP_SEARCH (   _heap)
Value:
do { \
fr_minmax_heap_foreach(trunk->_heap, trunk_connection_t, tconn) { \
if (ptr == tconn) { \
fr_fprintf(stderr, "trunk_search: tconn %p on " #_heap "\n", ptr); \
return true; \
} \
if (trunk_connection_search(tconn, ptr)) { \
fr_fprintf(stderr, " on tconn %p on " #_heap "\n", tconn); \
return true; \
} \
}}\
} while (0)

◆ TCONN_MINMAX_HEAP_VERIFY

#define TCONN_MINMAX_HEAP_VERIFY (   _heap,
  _state 
)
Value:
do {\
fr_minmax_heap_verify(file, line, trunk->_heap); \
fr_minmax_heap_foreach(trunk->_heap, trunk_connection_t, tconn) { \
trunk_connection_verify(file, line, tconn); \
TRUNK_TCONN_CHECKS(tconn, _state); \
}} \
} while (0)

◆ TCONN_TREQ_CHECKS

#define TCONN_TREQ_CHECKS (   _treq,
  _state 
)
Value:
do { \
fr_fatal_assert_msg(tconn == _treq->pub.tconn, \
"CONSISTENCY_CHECK_FAILED %s[%i}: trunk request-tconn mismatch", file, line); \
fr_fatal_assert_msg(tconn->pub.trunk == _treq->pub.trunk, \
"CONSISTENCY_CHECK_FAILED %s[%i}: trunk request-trunk mismatch", file, line); \
fr_fatal_assert_msg(_state == _treq->pub.state, \
"CONSISTENCY_CHECK_FAILED %s[%i}: trunk request-state mismatch", file, line); \
} while (0)

◆ TREQ_DLIST_SEARCH

#define TREQ_DLIST_SEARCH (   _dlist)
Value:
do { \
fr_dlist_foreach(&(tconn->_dlist), trunk_request_t, treq) { \
if (ptr == treq) { \
fr_fprintf(stderr, "trunk_search: treq %p on " #_dlist "\n", ptr); \
return true; \
} \
if (trunk_request_search(treq, ptr)) { \
fr_fprintf(stderr, "trunk_search: preq %p found on " #_dlist, ptr); \
return true; \
} \
} \
} while (0)
bool trunk_request_search(trunk_request_t *treq, void *ptr)
Definition: trunk.c:5201
Wraps a normal request.
Definition: trunk.c:97

◆ TREQ_DLIST_VERIFY

#define TREQ_DLIST_VERIFY (   _dlist,
  _state 
)
Value:
do { \
_fr_dlist_verify(file, line, &(tconn->_dlist)); \
fr_dlist_foreach(&(tconn->_dlist), trunk_request_t, treq) { \
trunk_request_verify(file, line, treq); \
TCONN_TREQ_CHECKS(treq, _state); \
} \
} while (0)

◆ TREQ_HEAP_SEARCH

#define TREQ_HEAP_SEARCH (   _heap)
Value:
do { \
fr_heap_iter_t _iter; \
for (trunk_request_t *treq = fr_heap_iter_init(tconn->_heap, &_iter); \
treq; \
treq = fr_heap_iter_next(tconn->_heap, &_iter)) { \
if (ptr == treq) { \
fr_fprintf(stderr, "trunk_search: treq %p in " #_heap "\n", ptr); \
return true; \
} \
if (trunk_request_search(treq, ptr)) { \
fr_fprintf(stderr, "trunk_search: preq %p found in " #_heap, ptr); \
return true; \
} \
} \
} while (0)
void * fr_heap_iter_init(fr_heap_t *h, fr_heap_iter_t *iter)
Iterate over entries in heap.
Definition: heap.c:351
void * fr_heap_iter_next(fr_heap_t *h, fr_heap_iter_t *iter)
Get the next entry in a heap.
Definition: heap.c:371

◆ TREQ_HEAP_VERIFY

#define TREQ_HEAP_VERIFY (   _heap,
  _state 
)
Value:
do { \
fr_heap_iter_t _iter; \
fr_heap_verify(file, line, tconn->_heap); \
for (trunk_request_t *treq = fr_heap_iter_init(tconn->_heap, &_iter); \
treq; \
treq = fr_heap_iter_next(tconn->_heap, &_iter)) { \
trunk_request_verify(file, line, treq); \
TCONN_TREQ_CHECKS(treq, _state); \
} \
} while (0)

◆ TREQ_OPTION_SEARCH

#define TREQ_OPTION_SEARCH (   _option)
Value:
do { \
if (tconn->_option) { \
if (ptr == tconn->_option) { \
fr_fprintf(stderr, "trunk_search: treq %p is " #_option "\n", ptr); \
return true; \
} \
if (trunk_request_search(tconn->_option, ptr)) { \
fr_fprintf(stderr, "trunk_search: preq %p found in " #_option, ptr); \
return true; \
} \
} \
} while (0)

◆ TREQ_OPTION_VERIFY

#define TREQ_OPTION_VERIFY (   _option,
  _state 
)
Value:
do { \
if (tconn->_option) { \
trunk_request_verify(file, line, tconn->_option); \
TCONN_TREQ_CHECKS(tconn->_option, _state); \
} \
} while (0)

◆ TRUNK_REQUEST_STATE_LOG_MAX

#define TRUNK_REQUEST_STATE_LOG_MAX   20

The maximum number of state logs to record per request.

Definition at line 69 of file trunk.c.

◆ TRUNK_STATE_TRANSITION

#define TRUNK_STATE_TRANSITION (   _new)
Value:
do { \
DEBUG3("Trunk changed state %s -> %s", \
fr_table_str_by_value(trunk_states, trunk->pub.state, "<INVALID>"), \
fr_table_str_by_value(trunk_states, _new, "<INVALID>")); \
CALL_WATCHERS(trunk, _new); \
trunk->pub.state = _new; \
} while (0)
static fr_table_num_ordered_t const trunk_states[]
Definition: trunk.c:392

Definition at line 881 of file trunk.c.

◆ TRUNK_TCONN_CHECKS

#define TRUNK_TCONN_CHECKS (   _tconn,
  _state 
)
Value:
do { \
fr_fatal_assert_msg(trunk == _tconn->pub.trunk, \
"CONSISTENCY_CHECK_FAILED %s[%i}: connection-trunk mismatch", file, line); \
fr_fatal_assert_msg(_state == _tconn->pub.state, \
"CONSISTENCY_CHECK_FAILED %s[%i}: connection-state mismatch", file, line); \
} while (0)

Typedef Documentation

◆ trunk_connection_t

Definition at line 1 of file trunk.c.

◆ trunk_request_t

Definition at line 1 of file trunk.c.

◆ trunk_t

typedef struct trunk_s trunk_t

Definition at line 1 of file trunk.c.

◆ trunk_watch_entry_t

An entry in a trunk watch function list.

Function Documentation

◆ _state_log_entry_free()

static int _state_log_entry_free ( trunk_request_state_log_t slog)
static

Used for sanity checks to ensure all log entries have been freed.

Definition at line 2778 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _trunk_connection_free()

static int _trunk_connection_free ( trunk_connection_t tconn)
static

Free a connection.

Enforces orderly free order of children of the tconn

Definition at line 3658 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _trunk_connection_lifetime_expire()

static void _trunk_connection_lifetime_expire ( UNUSED fr_event_list_t el,
UNUSED fr_time_t  now,
void *  uctx 
)
static

Trigger a reconnection of the trunk connection.

Parameters
[in]elEvent list the timer was inserted into.
[in]nowCurrent time.
[in]uctxThe tconn.

Definition at line 3420 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _trunk_connection_on_closed()

static void _trunk_connection_on_closed ( UNUSED connection_t conn,
UNUSED connection_state_t  prev,
UNUSED connection_state_t  state,
void *  uctx 
)
static

Connection failed after it was connected.

Reflect the connection state change in the lists we use to track connections.

Note
This function is only called from the connection API as a watcher.
Parameters
[in]connThe connection which changes state.
[in]prevThe connection is was in.
[in]stateThe connection is now in.
[in]uctxThe trunk_connection_t wrapping the connection.

Definition at line 3487 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _trunk_connection_on_connected()

static void _trunk_connection_on_connected ( UNUSED connection_t conn,
UNUSED connection_state_t  prev,
UNUSED connection_state_t  state,
void *  uctx 
)
static

Connection transitioned to the connected state.

Reflect the connection state change in the lists we use to track connections.

Note
This function is only called from the connection API as a watcher.
Parameters
[in]connThe connection which changes state.
[in]prevThe connection is was in.
[in]stateThe connection is now in.
[in]uctxThe trunk_connection_t wrapping the connection.

Definition at line 3438 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _trunk_connection_on_connecting()

static void _trunk_connection_on_connecting ( UNUSED connection_t conn,
UNUSED connection_state_t  prev,
UNUSED connection_state_t  state,
void *  uctx 
)
static

Connection transitioned to the connecting state.

Reflect the connection state change in the lists we use to track connections.

Note
This function is only called from the connection API as a watcher.
Parameters
[in]connThe connection which changes state.
[in]prevThe connection is was in.
[in]stateThe connection is now in.
[in]uctxThe trunk_connection_t wrapping the connection.

Definition at line 3342 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _trunk_connection_on_failed()

static void _trunk_connection_on_failed ( connection_t conn,
connection_state_t  prev,
connection_state_t  state,
void *  uctx 
)
static

Connection failed.

Parameters
[in]connThe connection which changes state.
[in]prevThe connection is was in.
[in]stateThe connection is now in.
[in]uctxThe trunk_connection_t wrapping the connection.

Definition at line 3558 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _trunk_connection_on_halted()

static void _trunk_connection_on_halted ( UNUSED connection_t conn,
UNUSED connection_state_t  prev,
UNUSED connection_state_t  state,
void *  uctx 
)
static

Connection transitioned to the halted state.

Remove the connection remove all lists, as it's likely about to be freed.

Setting the trunk back to the init state ensures that if the code is ever refactored and connection_signal_reconnect is used after a connection is halted, then everything is maintained in a valid state.

Note
This function is only called from the connection API as a watcher.
Parameters
[in]connThe connection which changes state.
[in]prevThe connection is was in.
[in]stateThe connection is now in.
[in]uctxThe trunk_connection_t wrapping the connection.

Definition at line 3610 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _trunk_connection_on_init()

static void _trunk_connection_on_init ( UNUSED connection_t conn,
UNUSED connection_state_t  prev,
UNUSED connection_state_t  state,
void *  uctx 
)
static

Connection transitioned to the the init state.

Reflect the connection state change in the lists we use to track connections.

Note
This function is only called from the connection API as a watcher.
Parameters
[in]connThe connection which changes state.
[in]prevThe connection is was in.
[in]stateThe connection is now in.
[in]uctxThe trunk_connection_t wrapping the connection.

Definition at line 3307 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _trunk_connection_on_shutdown()

static void _trunk_connection_on_shutdown ( UNUSED connection_t conn,
UNUSED connection_state_t  prev,
UNUSED connection_state_t  state,
void *  uctx 
)
static

Connection transitioned to the shutdown state.

If we're not already in the draining-to-free state, transition there now.

The idea is that if something signalled the connection to shutdown, we need to reflect that by dequeuing any pending requests, not accepting new ones, and waiting for the existing requests to complete.

Note
This function is only called from the connection API as a watcher.
Parameters
[in]connThe connection which changes state.
[in]prevThe connection is was in.
[in]stateThe connection is now in.
[in]uctxThe trunk_connection_t wrapping the connection.

Definition at line 3386 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _trunk_connection_order_by_shortest_queue()

static int8_t _trunk_connection_order_by_shortest_queue ( void const *  one,
void const *  two 
)
static

Order connections by queue depth.

Definition at line 4784 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _trunk_free()

static int _trunk_free ( trunk_t trunk)
static

Free a trunk, gracefully closing all connections.

Definition at line 4801 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _trunk_request_free()

static int _trunk_request_free ( trunk_request_t treq)
static

Actually free the trunk request.

Definition at line 2429 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _trunk_request_prioritise()

static int8_t _trunk_request_prioritise ( void const *  a,
void const *  b 
)
static

Compare two protocol requests.

Allows protocol requests to be prioritised with a function specified by the API client. Defaults to by pointer address if no function is specified.

Parameters
[in]atreq to compare to b.
[in]btreq to compare to a.
Returns
  • +1 if a > b.
  • 0 if a == b.
  • -1 if a < b.

Definition at line 935 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _trunk_timer()

static void _trunk_timer ( fr_event_list_t el,
fr_time_t  now,
void *  uctx 
)
static

Event to periodically call the connection management function.

Parameters
[in]elthis event belongs to.
[in]nowcurrent time.
[in]uctxThe trunk.

Definition at line 4450 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_add_watch()

trunk_watch_entry_t* trunk_add_watch ( trunk_t trunk,
trunk_state_t  state,
trunk_watch_t  watch,
bool  oneshot,
void const *  uctx 
)

Add a watch entry to the trunk state list.

Parameters
[in]trunkThe trunk to add the watcher to.
[in]stateto watch for.
[in]watchFunction to add.
[in]oneshotShould this watcher only be run once.
[in]uctxContext to pass to function.
Returns
  • NULL if an invalid state is passed.
  • A new watch entry handle on success.

Definition at line 861 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_alloc()

trunk_t* trunk_alloc ( TALLOC_CTX *  ctx,
fr_event_list_t el,
trunk_io_funcs_t const *  funcs,
trunk_conf_t const *  conf,
char const *  log_prefix,
void const *  uctx,
bool  delay_start 
)

Allocate a new collection of connections.

This function should be called first to allocate a new trunk connection.

After the trunk has been allocated, trunk_request_alloc and trunk_request_enqueue should be used to allocate memory for trunk requests, and pass a preq (protocol request) to the trunk for processing.

The trunk will then asynchronously process the request, writing the result to a specified rctx. See trunk_request_enqueue for more details.

Note
Trunks may not be shared between multiple threads under any circumstances.
Parameters
[in]ctxTo use for any memory allocations. Must be thread local.
[in]elto use for I/O and timer events.
[in]funcsCallback functions.
[in]confCommon user configurable parameters.
[in]log_prefixTo prepend to global messages.
[in]uctxUser data to pass to the alloc function.
[in]delay_startIf true, then we will not spawn any connections until the first request is enqueued.
Returns
  • New trunk handle on success.
  • NULL on error.

Definition at line 4885 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_backlog_drain()

static void trunk_backlog_drain ( trunk_t trunk)
static

Drain the backlog of as many requests as possible.

Parameters
[in]trunkTo drain backlog requests for.

Definition at line 4620 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_connection_auto_full()

static void trunk_connection_auto_full ( trunk_connection_t tconn)
inlinestatic

Automatically mark a connection as inactive.

Parameters
[in]tconnto potentially mark as inactive.

Definition at line 2886 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_connection_auto_unfull()

static void trunk_connection_auto_unfull ( trunk_connection_t tconn)
inlinestatic

Automatically mark a connection as active or reconnect it.

Parameters
[in]tconnto potentially mark as active or reconnect.

Definition at line 2927 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_connection_callback_readable()

void trunk_connection_callback_readable ( UNUSED fr_event_list_t el,
UNUSED int  fd,
UNUSED int  flags,
void *  uctx 
)

Standard I/O read function.

Underlying FD in now readable, so call the trunk to read any pending requests from this connection.

Parameters
[in]elThe event list signalling.
[in]fdthat's now readable.
[in]flagsdescribing the read event.
[in]uctxThe trunk connection handle (tconn).

Definition at line 3992 of file trunk.c.

+ Here is the call graph for this function:

◆ trunk_connection_callback_writable()

void trunk_connection_callback_writable ( UNUSED fr_event_list_t el,
UNUSED int  fd,
UNUSED int  flags,
void *  uctx 
)

Standard I/O write function.

Underlying FD is now writable, so call the trunk to write any pending requests to this connection.

Parameters
[in]elThe event list signalling.
[in]fdthat's now writable.
[in]flagsdescribing the write event.
[in]uctxThe trunk connection handle (tcon).

Definition at line 4009 of file trunk.c.

+ Here is the call graph for this function:

◆ trunk_connection_close_if_empty()

static void trunk_connection_close_if_empty ( trunk_t trunk,
fr_dlist_head_t head 
)
static

Close connections in a particular connection list if they have no requests associated with them.

Parameters
[in]trunkcontaining connections we want to close.
[in]headof list of connections to examine.

Definition at line 4035 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_connection_count_by_state()

uint16_t trunk_connection_count_by_state ( trunk_t trunk,
int  conn_state 
)

Return the count number of connections in the specified states.

Parameters
[in]trunkto retrieve counts for.
[in]conn_stateOne or more trunk_connection_state_t states or'd together.
Returns
The number of connections in the specified states.

Definition at line 2843 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_connection_enter_active()

static void trunk_connection_enter_active ( trunk_connection_t tconn)
static

Transition a connection back to the active state.

This should only be called on a connection which is in the full state, inactive state, draining state or connecting state.

Definition at line 3236 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_connection_enter_draining()

static void trunk_connection_enter_draining ( trunk_connection_t tconn)
static

Transition a connection to the draining state.

Removes the connection from the active heap so it won't be assigned any new connections.

Definition at line 3168 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_connection_enter_draining_to_free()

static void trunk_connection_enter_draining_to_free ( trunk_connection_t tconn)
static

Transition a connection to the draining-to-reconnect state.

Removes the connection from the active heap so it won't be assigned any new connections.

Definition at line 3200 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_connection_enter_full()

static void trunk_connection_enter_full ( trunk_connection_t tconn)
static

Transition a connection to the full state.

Called whenever a trunk connection is at the maximum number of requests. Removes the connection from the connected heap, and places it in the full list.

Definition at line 3093 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_connection_enter_inactive()

static void trunk_connection_enter_inactive ( trunk_connection_t tconn)
static

Transition a connection to the inactive state.

Called whenever the API client wants to stop new requests being enqueued on a trunk connection.

Definition at line 3115 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_connection_enter_inactive_draining()

static void trunk_connection_enter_inactive_draining ( trunk_connection_t tconn)
static

Transition a connection to the inactive-draining state.

Called whenever the trunk manager wants to drain an inactive connection of its requests.

Definition at line 3138 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_connection_event_update()

static void trunk_connection_event_update ( trunk_connection_t tconn)
static

Update the registrations for I/O events we're interested in.

Definition at line 2973 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_connection_in_state()

bool trunk_connection_in_state ( trunk_connection_t tconn,
int  state 
)

Returns true if the trunk connection is in one of the specified states.

Parameters
[in]tconnTo check state for.
[in]stateto check
Returns
  • True if trunk connection is in a particular state.
  • False if trunk connection is not in a particular state.

Definition at line 4025 of file trunk.c.

◆ trunk_connection_is_full()

static bool trunk_connection_is_full ( trunk_connection_t tconn)
inlinestatic

Return whether a trunk connection should currently be considered full.

Parameters
[in]tconnto check.
Returns
  • true if the connection is full.
  • false if the connection is not full.

Definition at line 2909 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_connection_manage_schedule()

int trunk_connection_manage_schedule ( trunk_t trunk)

Schedule a trunk management event for the next time the event loop is executed.

Definition at line 4769 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_connection_manage_start()

void trunk_connection_manage_start ( trunk_t trunk)

Allow the trunk to open and close connections in response to load.

Definition at line 4748 of file trunk.c.

◆ trunk_connection_manage_stop()

void trunk_connection_manage_stop ( trunk_t trunk)

Stop the trunk from opening and closing connections in response to load.

Definition at line 4759 of file trunk.c.

◆ trunk_connection_pop_cancellation()

int trunk_connection_pop_cancellation ( trunk_request_t **  treq_out,
trunk_connection_t tconn 
)

Pop a cancellation request off a connection's cancellation queue.

The request we return is advanced by the request moving out of the cancel state and into the cancel_sent or cancel_complete state.

One of these signalling functions must be called after the request has been popped:

Parameters
[out]treq_outto process
[in]tconnConnection to drain cancellation request from.
Returns
  • 1 if no more requests.
  • 0 if a new request was written to treq_out.
  • -1 if the connection was previously freed. Caller MUST NOT touch any memory or requests associated with the connection.
  • -2 if called outside of the cancel muxer.

Definition at line 3813 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_connection_pop_request()

int trunk_connection_pop_request ( trunk_request_t **  treq_out,
trunk_connection_t tconn 
)

Pop a request off a connection's pending queue.

The request we return is advanced by the request moving out of the partial or pending states, when the mux function signals us.

If the same request is returned again and again, it means the muxer isn't actually doing anything with the request we returned, and it's and error in the muxer code.

One of these signalling functions must be used after the request has been popped:

  • trunk_request_signal_complete The request was completed. Either we got a synchronous response, or we knew the response without contacting an external server (cache).
  • trunk_request_signal_fail Failed muxing the request due to a permanent issue, i.e. an invalid request.
  • trunk_request_signal_partial Wrote part of a request. This request will be returned on the next call to this function so that the request_mux function can finish writing it. Only useful for stream type connections. Datagram type connections cannot have partial writes.
  • trunk_request_signal_sent Successfully sent a request.
Parameters
[out]treq_outto process
[in]tconnto pop a request from.
Returns
  • 1 if no more requests.
  • 0 if a new request was written to treq_out.
  • -1 if the connection was previously freed. Caller MUST NOT touch any memory or requests associated with the connection.
  • -2 if called outside of the muxer.

Definition at line 3861 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_connection_readable()

static void trunk_connection_readable ( trunk_connection_t tconn)
inlinestatic

A connection is readable.

Call the request_demux function to read pending requests

Definition at line 2940 of file trunk.c.

+ Here is the caller graph for this function:

◆ trunk_connection_remove()

static void trunk_connection_remove ( trunk_connection_t tconn)
static

Remove a trunk connection from whichever list it's currently in.

Parameters
[in]tconnto remove.

Definition at line 3037 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_connection_requests_dequeue()

static uint64_t trunk_connection_requests_dequeue ( fr_dlist_head_t out,
trunk_connection_t tconn,
int  states,
uint64_t  max 
)
static

Shift requests in the specified states onto new connections.

This function will blindly dequeue any requests in the specified state and get them back to the unassigned state, cancelling any sent or partially sent requests.

This function does not check that dequeuing a request in a particular state is a sane or sensible thing to do, that's up to the caller!

Parameters
[out]outA list to insert the newly dequeued and unassigned requests into.
[in]tconnto dequeue requests from.
[in]statesDequeue request in these states.
[in]maxThe maximum number of requests to dequeue. 0 for unlimited.

Definition at line 1730 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_connection_requests_requeue()

uint64_t trunk_connection_requests_requeue ( trunk_connection_t tconn,
int  states,
uint64_t  max,
bool  fail_bound 
)

Move requests off of a connection and requeue elsewhere.

Note
We don't re-queue on draining or draining to free, as requests should have already been moved off of the connection. It's also dangerous as the trunk management code main clean up a connection in this state when it's run on re-queue, and then the caller may try and access a now freed connection.
Parameters
[in]tconnto move requests off of.
[in]statesOnly move requests in this state.
[in]maxThe maximum number of requests to dequeue. 0 for unlimited.
[in]fail_boundIf true causes any requests bound to the connection to fail. If false bound requests will not be moved.
Returns
The number of requests requeued.

Definition at line 2003 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_connection_requests_requeue_priv()

static uint64_t trunk_connection_requests_requeue_priv ( trunk_connection_t tconn,
int  states,
uint64_t  max,
bool  fail_bound 
)
static

Remove requests in specified states from a connection, attempting to distribute them to new connections.

Parameters
[in]tconnTo remove requests from.
[in]statesOne or more states or'd together.
[in]maxThe maximum number of requests to dequeue. 0 for unlimited.
[in]fail_boundIf true causes any requests bound to the connection to fail. If false bound requests will not be moved.
Returns
the number of requests re-queued.

Definition at line 1841 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_connection_search()

bool trunk_connection_search ( trunk_connection_t tconn,
void *  ptr 
)

Definition at line 5143 of file trunk.c.

◆ trunk_connection_signal_active()

void trunk_connection_signal_active ( trunk_connection_t tconn)

Signal a trunk connection is no longer full.

Parameters
[in]tconnto signal.

Definition at line 3938 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_connection_signal_inactive()

void trunk_connection_signal_inactive ( trunk_connection_t tconn)

Signal a trunk connection cannot accept more requests.

Parameters
[in]tconnto signal.

Definition at line 3915 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_connection_signal_readable()

void trunk_connection_signal_readable ( trunk_connection_t tconn)

Signal that a trunk connection is readable.

Should be called from the 'read' I/O handler to signal that requests should be dequeued.

Parameters
[in]tconnto signal.

Definition at line 3899 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_connection_signal_reconnect()

void trunk_connection_signal_reconnect ( trunk_connection_t tconn,
connection_reason_t  reason 
)

Signal a trunk connection is no longer viable.

Parameters
[in]tconnto signal.
[in]reasonthe connection is being reconnected.

Definition at line 3977 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_connection_signal_writable()

void trunk_connection_signal_writable ( trunk_connection_t tconn)

Signal that a trunk connection is writable.

Should be called from the 'write' I/O handler to signal that requests can be enqueued.

Parameters
[in]tconnto signal.

Definition at line 3881 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_connection_spawn()

static int trunk_connection_spawn ( trunk_t trunk,
fr_time_t  now 
)
static

Attempt to spawn a new connection.

Calls the API client's alloc() callback to create a new connection_t, then inserts the connection into the 'connecting' list.

Parameters
[in]trunkto spawn connection in.
[in]nowThe current time.

Definition at line 3726 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_connection_verify()

void trunk_connection_verify ( char const *  file,
int  line,
trunk_connection_t tconn 
)

Definition at line 5027 of file trunk.c.

◆ trunk_connection_writable()

static void trunk_connection_writable ( trunk_connection_t tconn)
inlinestatic

A connection is writable.

Call the request_mux function to write pending requests

Definition at line 2950 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_del_watch()

int trunk_del_watch ( trunk_t trunk,
trunk_state_t  state,
trunk_watch_t  watch 
)

Remove a watch function from a trunk state list.

Parameters
[in]trunkThe trunk to remove the watcher from.
[in]stateto remove the watch from.
[in]watchFunction to remove.
Returns
  • 0 if the function was removed successfully.
  • -1 if the function wasn't present in the watch list.
  • -2 if an invalid state was passed.

Definition at line 827 of file trunk.c.

+ Here is the call graph for this function:

◆ trunk_manage()

static void trunk_manage ( trunk_t trunk,
fr_time_t  now 
)
static

Implements the algorithm we use to manage requests per connection levels.

This is executed periodically using a timer event, and opens/closes connections.

The aim is to try and keep the request per connection level in a sweet spot, where there's enough outstanding work for the connection/pipelining to work efficiently, but not so much so that we encounter increased latency.

In the request enqueue and dequeue functions we record every time the average number of requests per connection goes above the target count and record every time the average number of requests per connection goes below the target count.

This may sound expensive, but in all cases we're just summing counters. CPU time required does not increase with additional requests, only with large numbers of connections.

If we do encounter scaling issues, we can always maintain the counters as aggregates as an optimisation later.

If when the management function runs, the trunk was above the target most recently, we:

  • Return if we've been in this state for a shorter period than 'open_delay'.
  • Return if we're at max.
  • Return if opening a new connection will take us below the load target.
  • Return if we last opened a connection within 'open_delay'.
  • Otherwise we attempt to open a new connection.

If the trunk we below the target most recently, we:

  • Return if we've been in this state for a shorter period than 'close_delay'.
  • Return if we're at min.
  • Return if we have no connections.
  • Close a connection if min is 0, and we have no outstanding requests. Then return.
  • Return if closing a new connection will take us above the load target.
  • Return if we last closed a connection within 'closed_delay'.
  • Otherwise we move a connection to draining state.

Definition at line 4141 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_rebalance()

static void trunk_rebalance ( trunk_t trunk)
static

Rebalance connections across active trunk members when a new connection becomes active.

We don't have any visibility into the connection prioritisation algorithm it's essentially a black box.

We can however determine when the correct level of requests per connection has been reached, by dequeuing and requeing requests up until the point where the connection that just had a request dequeued, receives the same request back.

Parameters
[in]trunkThe trunk to rebalance.

Definition at line 4077 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_reconnect()

void trunk_reconnect ( trunk_t trunk,
int  states,
connection_reason_t  reason 
)

Force the trunk to re-establish its connections.

Parameters
[in]trunkto signal.
[in]statesOne or more states or'd together.
[in]reasonWhy the connections are being signalled to reconnect.

Definition at line 4675 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_request_alloc()

trunk_request_t* trunk_request_alloc ( trunk_t trunk,
request_t request 
)

(Pre-)Allocate a new trunk request

If trunk->conf.req_pool_headers or trunk->conf.req_pool_size are not zero then the request will be a talloc pool, which can be used to hold the preq.

Note
Do not use MEM to check the result of this allocated as it may fail for non-fatal reasons.
Parameters
[in]trunkto add request to.
[in]requestto wrap in a trunk request (treq).
Returns
  • A newly allocated request.
  • NULL if too many requests are allocated.

Definition at line 2462 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_request_check_enqueue()

static trunk_enqueue_t trunk_request_check_enqueue ( trunk_connection_t **  tconn_out,
trunk_t trunk,
request_t request 
)
static

Check to see if a trunk request can be enqueued.

Parameters
[out]tconn_outConnection the request may be enqueued on.
[in]trunkTo enqueue requests on.
[in]requestassociated with the treq (if any).
Returns
  • TRUNK_ENQUEUE_OK caller should enqueue request on provided tconn.
  • TRUNK_ENQUEUE_IN_BACKLOG Request should be queued in the backlog.
  • TRUNK_ENQUEUE_NO_CAPACITY Unable to enqueue request as we have no spare connections or backlog space.
  • TRUNK_ENQUEUE_DST_UNAVAILABLE Can't enqueue because the destination is unreachable.

Definition at line 1595 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_request_count_by_connection()

uint32_t trunk_request_count_by_connection ( trunk_connection_t const *  tconn,
int  req_state 
)

Return the count number of requests associated with a trunk connection.

Parameters
[in]tconnto return request count for.
[in]req_stateOne or more request states or'd together.
Returns
The number of requests in the specified states, associated with a tconn.

Definition at line 2867 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_request_count_by_state()

uint64_t trunk_request_count_by_state ( trunk_t trunk,
int  conn_state,
int  req_state 
)

Return a count of requests on a connection in a specific state.

Parameters
[in]trunkto retrieve counts for.
[in]conn_stateOne or more connection states or'd together.
[in]req_stateOne or more request states or'd together.
Returns
The number of requests in a particular state, on connection in a particular state.

Definition at line 4472 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_request_enqueue()

trunk_enqueue_t trunk_request_enqueue ( trunk_request_t **  treq_out,
trunk_t trunk,
request_t request,
void *  preq,
void *  rctx 
)

Enqueue a request that needs data written to the trunk.

When a request_t * needs to make an asynchronous request to an external datastore it should call this function, specifying a preq (protocol request) containing the data necessary to request information from the external datastore, and an rctx (resume ctx) used to hold the decoded response and/or any error codes.

After a treq is successfully enqueued it will either be assigned immediately to the pending queue of a connection, or if no connections are available, (depending on the trunk configuration) the treq will be placed in the trunk's global backlog.

After receiving a positive return code from this function the caller should immediately yield, to allow the various timers and I/O handlers that drive tconn (trunk connection) and treq state changes to be called.

When a tconn becomes writable (or the trunk is configured to be always writable) the trunk_request_mux_t callback will be called to dequeue, encode and send any pending requests for that tconn. The trunk_request_mux_t callback is also responsible for tracking the outbound requests to allow the trunk_request_demux_t callback to match inbound responses with the original treq. Once the trunk_request_mux_t callback is done processing the treq it signals what state the treq should enter next using one of the trunk_request_signal_* functions.

When a tconn becomes readable the user specified trunk_request_demux_t callback is called to process any responses, match them with the original treq. and signal what state they should enter next using one of the trunk_request_signal_* functions.

Parameters
[in,out]treq_outA trunk request handle. If the memory pointed to is NULL, a new treq will be allocated. Otherwise treq should point to memory allocated with trunk_request_alloc.
[in]trunkto enqueue request on.
[in]requestto enqueue.
[in]preqProtocol request to write out. Will be freed when treq is freed. Should ideally be parented by the treq if possible. Use trunk_request_alloc for pre-allocation of the treq.
[in]rctxThe resume context to write any result to.
Returns
  • TRUNK_ENQUEUE_OK.
  • TRUNK_ENQUEUE_IN_BACKLOG.
  • TRUNK_ENQUEUE_NO_CAPACITY.
  • TRUNK_ENQUEUE_DST_UNAVAILABLE
  • TRUNK_ENQUEUE_FAIL

Definition at line 2575 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_request_enqueue_existing()

static trunk_enqueue_t trunk_request_enqueue_existing ( trunk_request_t treq)
static

Enqueue a request which has never been assigned to a connection or was previously cancelled.

Parameters
[in]treqto re enqueue. Must have been removed from its existing connection with trunk_connection_requests_dequeue.
Returns
  • TRUNK_ENQUEUE_OK Request was re-enqueued.
  • TRUNK_ENQUEUE_NO_CAPACITY Request enqueueing failed because we're at capacity.
  • TRUNK_ENQUEUE_DST_UNAVAILABLE Enqueuing failed for some reason. Usually because the connection to the resource is down.

Definition at line 1673 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_request_enqueue_on_conn()

trunk_enqueue_t trunk_request_enqueue_on_conn ( trunk_request_t **  treq_out,
trunk_connection_t tconn,
request_t request,
void *  preq,
void *  rctx,
bool  ignore_limits 
)

Enqueue additional requests on a specific connection.

This may be used to create a series of requests on a single connection, or to generate in-band status checks.

Note
If conf->always_writable, then the muxer will be called immediately. The caller must be able to handle multiple calls to its muxer gracefully.
Parameters
[in,out]treq_outA trunk request handle. If the memory pointed to is NULL, a new treq will be allocated. Otherwise treq should point to memory allocated with trunk_request_alloc.
[in]tconnto enqueue request on.
[in]requestto enqueue.
[in]preqProtocol request to write out. Will be freed when treq is freed. Should ideally be parented by the treq if possible. Use trunk_request_alloc for pre-allocation of the treq.
[in]rctxThe resume context to write any result to.
[in]ignore_limitsIgnore max_req_per_conn. Useful to force status checks through even if the connection is at capacity. Will also allow enqueuing on "inactive", "draining", "draining-to-free" connections.
Returns
  • TRUNK_ENQUEUE_OK.
  • TRUNK_ENQUEUE_NO_CAPACITY - At max_req_per_conn_limit
  • TRUNK_ENQUEUE_DST_UNAVAILABLE - Connection cannot service requests.

Definition at line 2729 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_request_enter_backlog()

static void trunk_request_enter_backlog ( trunk_request_t treq,
bool  new 
)
static

Transition a request to the backlog state, adding it to the backlog of the trunk.

Note
treq->tconn and treq may be inviable after calling if treq->conn and connection_signals_pause are not used. This is due to call to trunk_manage.
Parameters
[in]treqto trigger a state change for.
[in]newWhether this is a new request.

Definition at line 1088 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_request_enter_cancel()

static void trunk_request_enter_cancel ( trunk_request_t treq,
trunk_cancel_reason_t  reason 
)
static

Transition a request to the cancel state, placing it in a connection's cancellation list.

If a request_cancel_send callback is provided, that callback will be called periodically for requests which were cancelled due to a signal.

The request_cancel_send callback will dequeue cancelled requests and inform a remote server that the result is no longer required.

A request must enter this state before being added to the backlog of another connection if it's been sent or partially sent.

Note
treq->tconn and treq may be inviable after calling if treq->conn and connection_signals_pause is not used. This is due to call to trunk_connection_event_update.
Parameters
[in]treqto trigger a state change for.
[in]reasonWhy the request was cancelled. Should be one of:
  • TRUNK_CANCEL_REASON_SIGNAL request cancelled because of a signal from the interpreter.
  • TRUNK_CANCEL_REASON_MOVE request cancelled because the connection failed and it needs to be assigned to a new connection.
  • TRUNK_CANCEL_REASON_REQUEUE request cancelled as it needs to be resent on the same connection.

Definition at line 1366 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_request_enter_cancel_complete()

static void trunk_request_enter_cancel_complete ( trunk_request_t treq)
static

Cancellation was acked, the request is complete, free it.

The API client will not be informed, as the original request_t * will likely have been freed by this point.

Note
treq will be inviable after a call to this function. treq->tconn may be inviable after calling if treq->conn and connection_signals_pause is not used. This is due to call to trunk_request_remove_from_conn.
Parameters
[in]treqto mark as complete.

Definition at line 1497 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_request_enter_cancel_partial()

static void trunk_request_enter_cancel_partial ( trunk_request_t treq)
static

Transition a request to the cancel_partial state, placing it in a connection's cancel_partial slot.

The request_demux function is then responsible for signalling that the cancel request is complete when the remote server acknowledges the cancellation request.

Parameters
[in]treqto trigger a state change for.

Definition at line 1417 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_request_enter_cancel_sent()

static void trunk_request_enter_cancel_sent ( trunk_request_t treq)
static

Transition a request to the cancel_sent state, placing it in a connection's cancel_sent list.

The request_demux function is then responsible for signalling that the cancel request is complete when the remote server acknowledges the cancellation request.

Note
treq->tconn and treq may be inviable after calling if treq->conn and connection_signals_pause is not used. This is due to call to trunk_connection_event_update.
Parameters
[in]treqto trigger a state change for.

Definition at line 1452 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_request_enter_complete()

static void trunk_request_enter_complete ( trunk_request_t treq)
static

Request completed successfully, inform the API client and free the request.

Note
treq will be inviable after a call to this function. treq->tconn may also be inviable due to call to trunk_request_remove_from_conn.
Parameters
[in]treqto mark as complete.

Definition at line 1528 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_request_enter_failed()

static void trunk_request_enter_failed ( trunk_request_t treq)
static

Request failed, inform the API client and free the request.

Note
treq will be inviable after a call to this function. treq->tconn may also be inviable due to call to trunk_request_remove_from_conn.
Parameters
[in]treqto mark as failed.

Definition at line 1559 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_request_enter_partial()

static void trunk_request_enter_partial ( trunk_request_t treq)
static

Transition a request to the partial state, indicating that is has been partially sent.

Parameters
[in]treqto trigger a state change for.

Definition at line 1221 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_request_enter_pending()

static void trunk_request_enter_pending ( trunk_request_t treq,
trunk_connection_t tconn,
bool  new 
)
static

Transition a request to the pending state, adding it to the backlog of an active connection.

All trunk requests being added to a connection get passed to this function. All trunk requests being removed from a connection get passed to trunk_request_remove_from_conn.

Note
treq->tconn and treq may be inviable after calling if treq->conn and connection_signals_pause is not used. This is due to call to trunk_connection_event_update.
Parameters
[in]treqto trigger a state change for.
[in]tconnto enqueue the request on.
[in]newWhether this is a new request.

Definition at line 1150 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_request_enter_reapable()

static void trunk_request_enter_reapable ( trunk_request_t treq)
static

Transition a request to the reapable state, indicating that it's been sent in its entirety, but no response is expected.

Note
Largely a replica of trunk_request_enter_sent.
Parameters
[in]treqto trigger a state change for.

Definition at line 1304 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_request_enter_sent()

static void trunk_request_enter_sent ( trunk_request_t treq)
static

Transition a request to the sent state, indicating that it's been sent in its entirety.

Note
treq->tconn and treq may be inviable after calling if treq->conn and connection_signals_pause is not used. This is due to call to trunk_connection_event_update.
Parameters
[in]treqto trigger a state change for.

Definition at line 1251 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_request_enter_unassigned()

static void trunk_request_enter_unassigned ( trunk_request_t treq)
static

Transition a request to the unassigned state, in preparation for re-assignment.

Note
treq->tconn may be inviable after calling if treq->conn and connection_signals_pause are not used. This is due to call to trunk_request_remove_from_conn.
Parameters
[in]treqto trigger a state change for.

Definition at line 1053 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_request_free()

void trunk_request_free ( trunk_request_t **  treq_to_free)

If the trunk request is freed then update the target requests.

gperftools showed calling the request free function directly was slightly faster than using talloc_free.

Parameters
[in]treq_to_freerequest.

Definition at line 2310 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_request_remove_from_conn()

static void trunk_request_remove_from_conn ( trunk_request_t treq)
static

Remove a request from all connection lists.

A common function used by init, fail, complete state functions to disassociate a request from a connection in preparation for freeing or reassignment.

Despite its unassuming name, this function is the place to put calls to functions which need to be called when the number of requests associated with a connection changes.

Trunk requests will always be passed to this function before they're removed from a connection, even if the requests are being freed.

Parameters
[in]treqto trigger a state change for.

Definition at line 959 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_request_requeue()

trunk_enqueue_t trunk_request_requeue ( trunk_request_t treq)

Re-enqueue a request on the same connection.

If the treq has been sent, we assume that we're being signalled to requeue because something outside of the trunk API has determined that a retransmission is required. The easiest way to perform that retransmission is to clean up any tracking information for the request, and the requeue it for transmission.

IF re-queueing fails, the request will enter the fail state. It should not be accessed if this occurs.

Parameters
[in]treqto requeue (retransmit).
Returns
  • TRUNK_ENQUEUE_OK.
  • TRUNK_ENQUEUE_DST_UNAVAILABLE - Connection cannot service requests.
  • TRUNK_ENQUEUE_FAIL - Request isn't in a valid state to be reassigned.

Definition at line 2664 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_request_search()

bool trunk_request_search ( trunk_request_t treq,
void *  ptr 
)

Definition at line 5201 of file trunk.c.

◆ trunk_request_signal_cancel()

void trunk_request_signal_cancel ( trunk_request_t treq)

Cancel a trunk request.

treq can be in any state, but requests to cancel if the treq is not in the TRUNK_REQUEST_STATE_PARTIAL or TRUNK_REQUEST_STATE_SENT state will be ignored.

The complete or failed callbacks will not be called here, as it's assumed the request_t * is now inviable as it's being cancelled.

The free function however, is called, and that should be used to perform necessary cleanup.

Parameters
[in]treqto signal state change for.

Definition at line 2140 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_request_signal_cancel_complete()

void trunk_request_signal_cancel_complete ( trunk_request_t treq)

Signal that a remote server acked our cancellation.

Called from request_demux to indicate that it got an ack for the cancellation.

Parameters
[in]treqto signal state change for.

Definition at line 2272 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_request_signal_cancel_partial()

void trunk_request_signal_cancel_partial ( trunk_request_t treq)

Signal a partial cancel write.

Where there's high load, and the outbound write buffer is full

Parameters
[in]treqto signal state change for.

Definition at line 2224 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_request_signal_cancel_sent()

void trunk_request_signal_cancel_sent ( trunk_request_t treq)

Signal that a remote server has been notified of the cancellation.

Called from request_cancel_mux to indicate that the datastore has been informed that the response is no longer needed.

Parameters
[in]treqto signal state change for.

Definition at line 2248 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_request_signal_complete()

void trunk_request_signal_complete ( trunk_request_t treq)

Signal that a trunk request is complete.

The API client will be informed that the request is now complete.

Definition at line 2087 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_request_signal_fail()

void trunk_request_signal_fail ( trunk_request_t treq)

Signal that a trunk request failed.

The API client will be informed that the request has failed.

Definition at line 2120 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_request_signal_partial()

void trunk_request_signal_partial ( trunk_request_t treq)

Signal a partial write.

Where there's high load, and the outbound write buffer is full

Parameters
[in]treqto signal state change for.

Definition at line 2022 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_request_signal_reapable()

void trunk_request_signal_reapable ( trunk_request_t treq)

Signal that the request was written to a connection successfully, but no response is expected.

Parameters
[in]treqto signal state change for.

Definition at line 2065 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_request_signal_sent()

void trunk_request_signal_sent ( trunk_request_t treq)

Signal that the request was written to a connection successfully.

Parameters
[in]treqto signal state change for.

Definition at line 2043 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_request_state_log()

void trunk_request_state_log ( fr_log_t const *  log,
fr_log_type_t  log_type,
char const *  file,
int  line,
trunk_request_t const *  treq 
)

Definition at line 2816 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_request_state_log_entry_add()

void trunk_request_state_log_entry_add ( char const *  function,
int  line,
trunk_request_t treq,
trunk_request_state_t  new 
)

Definition at line 2785 of file trunk.c.

+ Here is the call graph for this function:

◆ trunk_request_verify()

void trunk_request_verify ( char const *  file,
int  line,
trunk_request_t treq 
)

Definition at line 5087 of file trunk.c.

+ Here is the call graph for this function:

◆ trunk_requests_per_connection()

static uint64_t trunk_requests_per_connection ( uint16_t conn_count_out,
uint32_t req_count_out,
trunk_t trunk,
fr_time_t  now,
NDEBUG_UNUSED bool  verify 
)
static

Update timestamps for when we last had a transition from above target to below target or vice versa.

Should be called on every time a connection or request is allocated or freed.

Parameters
[out]conn_count_outHow many connections we considered.
[out]req_count_outHow many requests we considered.
[in]trunkto operate on.
[in]nowThe current time.
[in]verifyif true (and this is a debug build), then assert if req_per_conn has changed.
Returns
  • 0 if the average couldn't be calculated (no requests or no connections).
  • The average number of requests per connection.

Definition at line 4521 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_search()

bool trunk_search ( trunk_t trunk,
void *  ptr 
)

Definition at line 5098 of file trunk.c.

◆ trunk_start()

int trunk_start ( trunk_t trunk)

Start the trunk running.

Definition at line 4714 of file trunk.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ trunk_verify()

void trunk_verify ( char const *  file,
int  line,
trunk_t trunk 
)

Verify a trunk.

A trunk has some number of connections, which each have some number of requests. The connections and requests are in differing kinds of containers depending on their state and how they are used, and may have fields that can only be validated by comparison with a parent. We had planned on passing a "context" down with the ancestral values, but that breaks the foo_verify() API. Each foo_verify() will only verify the foo's children.

Definition at line 4966 of file trunk.c.

+ Here is the call graph for this function:

◆ trunk_watch_call()

static void trunk_watch_call ( trunk_t trunk,
fr_dlist_head_t list,
trunk_state_t  state 
)
inlinestatic

Call a list of watch functions associated with a state.

Definition at line 785 of file trunk.c.

+ Here is the call graph for this function:

Variable Documentation

◆ request_counter

atomic_uint_fast64_t request_counter = ATOMIC_VAR_INIT(1)
static

Definition at line 52 of file trunk.c.

◆ trunk_cancellation_reasons

fr_table_num_ordered_t const trunk_cancellation_reasons[]
static
Initial value:
= {
{ L("TRUNK_CANCEL_REASON_NONE"), TRUNK_CANCEL_REASON_NONE },
{ L("TRUNK_CANCEL_REASON_SIGNAL"), TRUNK_CANCEL_REASON_SIGNAL },
{ L("TRUNK_CANCEL_REASON_MOVE"), TRUNK_CANCEL_REASON_MOVE },
{ L("TRUNK_CANCEL_REASON_REQUEUE"), TRUNK_CANCEL_REASON_REQUEUE }
}
#define L(_str)
Helper for initialising arrays of string literals.
Definition: build.h:207
@ TRUNK_CANCEL_REASON_NONE
Request has not been cancelled.
Definition: trunk.h:56
@ TRUNK_CANCEL_REASON_SIGNAL
Request cancelled due to a signal.
Definition: trunk.h:57
@ TRUNK_CANCEL_REASON_REQUEUE
A previously sent request is being requeued.
Definition: trunk.h:59
@ TRUNK_CANCEL_REASON_MOVE
Request cancelled because it's being moved.
Definition: trunk.h:58

Definition at line 413 of file trunk.c.

◆ trunk_cancellation_reasons_len

size_t trunk_cancellation_reasons_len = NUM_ELEMENTS(trunk_cancellation_reasons)
static

Definition at line 419 of file trunk.c.

◆ trunk_config

conf_parser_t const trunk_config[]
Initial value:
= {
{ FR_CONF_OFFSET("start", trunk_conf_t, start), .dflt = "1" },
{ FR_CONF_OFFSET("min", trunk_conf_t, min), .dflt = "1" },
{ FR_CONF_OFFSET("max", trunk_conf_t, max), .dflt = "5" },
{ FR_CONF_OFFSET("connecting", trunk_conf_t, connecting), .dflt = "2" },
{ FR_CONF_OFFSET("uses", trunk_conf_t, max_uses), .dflt = "0" },
{ FR_CONF_OFFSET("lifetime", trunk_conf_t, lifetime), .dflt = "0" },
{ FR_CONF_OFFSET("open_delay", trunk_conf_t, open_delay), .dflt = "0.2" },
{ FR_CONF_OFFSET("close_delay", trunk_conf_t, close_delay), .dflt = "10.0" },
{ FR_CONF_OFFSET("manage_interval", trunk_conf_t, manage_interval), .dflt = "0.2" },
{ FR_CONF_OFFSET("max_backlog", trunk_conf_t, max_backlog), .dflt = "1000" },
{ FR_CONF_OFFSET_SUBSECTION("connection", 0, trunk_conf_t, conn_conf, trunk_config_connection), .subcs_size = sizeof(trunk_config_connection) },
{ FR_CONF_POINTER("request", 0, CONF_FLAG_SUBSECTION, NULL), .subcs = (void const *) trunk_config_request },
}
#define CONF_PARSER_TERMINATOR
Definition: cf_parse.h:627
#define FR_CONF_OFFSET(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition: cf_parse.h:268
#define FR_CONF_POINTER(_name, _type, _flags, _res_p)
conf_parser_t which parses a single CONF_PAIR producing a single global result
Definition: cf_parse.h:310
#define FR_CONF_OFFSET_SUBSECTION(_name, _flags, _struct, _field, _subcs)
conf_parser_t which populates a sub-struct using a CONF_SECTION
Definition: cf_parse.h:297
@ CONF_FLAG_SUBSECTION
Instead of putting the information into a configuration structure, the configuration file routines MA...
Definition: cf_parse.h:399
static size_t min(size_t x, size_t y)
Definition: sbuff.c:143
static conf_parser_t const trunk_config_request[]
Definition: trunk.c:296
static conf_parser_t const trunk_config_connection[]
Definition: trunk.c:304
Common configuration parameters for a trunk.
Definition: trunk.h:224

Config parser definitions to populate a trunk_conf_t.

Definition at line 312 of file trunk.c.

◆ trunk_config_connection

conf_parser_t const trunk_config_connection[]
static
Initial value:
= {
{ FR_CONF_OFFSET("connect_timeout", connection_conf_t, connection_timeout), .dflt = "3.0" },
{ FR_CONF_OFFSET("reconnect_delay", connection_conf_t, reconnection_delay), .dflt = "1" },
}

Definition at line 304 of file trunk.c.

◆ trunk_config_request

conf_parser_t const trunk_config_request[]
static
Initial value:
= {
{ FR_CONF_OFFSET("per_connection_max", trunk_conf_t, max_req_per_conn), .dflt = "2000" },
{ FR_CONF_OFFSET("per_connection_target", trunk_conf_t, target_req_per_conn), .dflt = "1000" },
{ FR_CONF_OFFSET("free_delay", trunk_conf_t, req_cleanup_delay), .dflt = "10.0" },
}

Definition at line 296 of file trunk.c.

◆ trunk_conn_trigger_names

fr_table_num_indexed_bit_pos_t const trunk_conn_trigger_names[]
static
Initial value:
= {
{ L("pool.connection_halted"), TRUNK_CONN_HALTED },
{ L("pool.connection_init"), TRUNK_CONN_INIT },
{ L("pool.connection_connecting"), TRUNK_CONN_CONNECTING },
{ L("pool.connection_active"), TRUNK_CONN_ACTIVE },
{ L("pool.connection_closed"), TRUNK_CONN_CLOSED },
{ L("pool.connection_full"), TRUNK_CONN_FULL },
{ L("pool.connection_inactive"), TRUNK_CONN_INACTIVE },
{ L("pool.connection_inactive_draining"), TRUNK_CONN_INACTIVE_DRAINING },
{ L("pool.connection_draining"), TRUNK_CONN_DRAINING },
{ L("pool.connection_draining_to_free"), TRUNK_CONN_DRAINING_TO_FREE }
}
@ TRUNK_CONN_FULL
Connection is full and can't accept any more requests.
Definition: trunk.h:95
@ TRUNK_CONN_CONNECTING
Connection is connecting.
Definition: trunk.h:90
@ TRUNK_CONN_DRAINING
Connection will be closed once it has no more outstanding requests, if it's not reactivated.
Definition: trunk.h:101
@ TRUNK_CONN_INACTIVE_DRAINING
Connection is inactive, can't accept any more requests, and will be closed once it has no more outsta...
Definition: trunk.h:97
@ TRUNK_CONN_INACTIVE
Connection is inactive and can't accept any more requests.
Definition: trunk.h:96
@ TRUNK_CONN_HALTED
Halted, ready to be freed.
Definition: trunk.h:88
@ TRUNK_CONN_CLOSED
Connection was closed, either explicitly or due to failure.
Definition: trunk.h:94
@ TRUNK_CONN_INIT
In the initial state.
Definition: trunk.h:89
@ TRUNK_CONN_DRAINING_TO_FREE
Connection will be closed once it has no more outstanding requests.
Definition: trunk.h:103

Map connection states to trigger names.

Must stay in the same order as trunk_connection_state_t

Definition at line 378 of file trunk.c.

◆ trunk_conn_trigger_names_len

size_t trunk_conn_trigger_names_len = NUM_ELEMENTS(trunk_conn_trigger_names)
static

Definition at line 390 of file trunk.c.

◆ trunk_connection_events

fr_table_num_ordered_t const trunk_connection_events[]
static
Initial value:
= {
{ L("TRUNK_CONN_EVENT_NONE"), TRUNK_CONN_EVENT_NONE },
{ L("TRUNK_CONN_EVENT_READ"), TRUNK_CONN_EVENT_READ },
{ L("TRUNK_CONN_EVENT_WRITE"), TRUNK_CONN_EVENT_WRITE },
{ L("TRUNK_CONN_EVENT_BOTH"), TRUNK_CONN_EVENT_BOTH },
}
@ TRUNK_CONN_EVENT_BOTH
Trunk should be notified if a connection is readable or writable.
Definition: trunk.h:79
@ TRUNK_CONN_EVENT_WRITE
Trunk should be notified if a connection is writable.
Definition: trunk.h:77
@ TRUNK_CONN_EVENT_NONE
Don't notify the trunk on connection state changes.
Definition: trunk.h:73
@ TRUNK_CONN_EVENT_READ
Trunk should be notified if a connection is readable.
Definition: trunk.h:75

Definition at line 421 of file trunk.c.

◆ trunk_connection_events_len

size_t trunk_connection_events_len = NUM_ELEMENTS(trunk_connection_events)
static

Definition at line 427 of file trunk.c.

◆ trunk_connection_states

fr_table_num_ordered_t const trunk_connection_states[]
static
Initial value:
= {
{ L("INIT"), TRUNK_CONN_INIT },
{ L("HALTED"), TRUNK_CONN_HALTED },
{ L("CONNECTING"), TRUNK_CONN_CONNECTING },
{ L("ACTIVE"), TRUNK_CONN_ACTIVE },
{ L("CLOSED"), TRUNK_CONN_CLOSED },
{ L("FULL"), TRUNK_CONN_FULL },
{ L("INACTIVE"), TRUNK_CONN_INACTIVE },
{ L("INACTIVE-DRAINING"), TRUNK_CONN_INACTIVE_DRAINING },
{ L("DRAINING"), TRUNK_CONN_DRAINING },
{ L("DRAINING-TO-FREE"), TRUNK_CONN_DRAINING_TO_FREE }
}

Definition at line 399 of file trunk.c.

◆ trunk_connection_states_len

size_t trunk_connection_states_len = NUM_ELEMENTS(trunk_connection_states)
static

Definition at line 411 of file trunk.c.

◆ trunk_req_trigger_names

fr_table_num_indexed_bit_pos_t const trunk_req_trigger_names[]
static
Initial value:
= {
{ L("pool.request_init"), TRUNK_REQUEST_STATE_INIT },
{ L("pool.request_unassigned"), TRUNK_REQUEST_STATE_UNASSIGNED },
{ L("pool.request_backlog"), TRUNK_REQUEST_STATE_BACKLOG },
{ L("pool.request_pending"), TRUNK_REQUEST_STATE_PENDING },
{ L("pool.request_partial"), TRUNK_REQUEST_STATE_PARTIAL },
{ L("pool.request_sent"), TRUNK_REQUEST_STATE_SENT },
{ L("pool.request_state_reapable"), TRUNK_REQUEST_STATE_REAPABLE },
{ L("pool.request_complete"), TRUNK_REQUEST_STATE_COMPLETE },
{ L("pool.request_state_failed"), TRUNK_REQUEST_STATE_FAILED },
{ L("pool.request_state_cancel"), TRUNK_REQUEST_STATE_CANCEL },
{ L("pool.request_state_cancel_sent"), TRUNK_REQUEST_STATE_CANCEL_SENT },
{ L("pool.request_state_cancel_partial"), TRUNK_REQUEST_STATE_CANCEL_PARTIAL },
{ L("pool.request_state_cancel_complete"), TRUNK_REQUEST_STATE_CANCEL_COMPLETE },
}
@ TRUNK_REQUEST_STATE_PARTIAL
Some of the request was written to the socket, more of it should be written later.
Definition: trunk.h:170
@ TRUNK_REQUEST_STATE_REAPABLE
Request has been written, needs to persist, but we are not currently waiting for any response.
Definition: trunk.h:173
@ TRUNK_REQUEST_STATE_UNASSIGNED
Transition state - Request currently not assigned to any connection.
Definition: trunk.h:165
@ TRUNK_REQUEST_STATE_INIT
Initial state.
Definition: trunk.h:162
@ TRUNK_REQUEST_STATE_CANCEL_SENT
We've informed the remote server that the request has been cancelled.
Definition: trunk.h:185
@ TRUNK_REQUEST_STATE_COMPLETE
The request is complete.
Definition: trunk.h:182
@ TRUNK_REQUEST_STATE_FAILED
The request failed.
Definition: trunk.h:183
@ TRUNK_REQUEST_STATE_CANCEL
A request on a particular socket was cancel.
Definition: trunk.h:184
@ TRUNK_REQUEST_STATE_CANCEL_PARTIAL
We partially wrote a cancellation request.
Definition: trunk.h:187
@ TRUNK_REQUEST_STATE_BACKLOG
In the backlog.
Definition: trunk.h:167
@ TRUNK_REQUEST_STATE_CANCEL_COMPLETE
Remote server has acknowledged our cancellation.
Definition: trunk.h:188
@ TRUNK_REQUEST_STATE_PENDING
In the queue of a connection and is pending writing.
Definition: trunk.h:168
@ TRUNK_REQUEST_STATE_SENT
Was written to a socket. Waiting for a response.
Definition: trunk.h:172

Map request states to trigger names.

Must stay in the same order as trunk_connection_state_t

Definition at line 339 of file trunk.c.

◆ trunk_req_trigger_names_len

size_t trunk_req_trigger_names_len = NUM_ELEMENTS(trunk_req_trigger_names)
static

Definition at line 354 of file trunk.c.

◆ trunk_request_states

fr_table_num_ordered_t const trunk_request_states[]
static
Initial value:
= {
{ L("UNASSIGNED"), TRUNK_REQUEST_STATE_UNASSIGNED },
{ L("BACKLOG"), TRUNK_REQUEST_STATE_BACKLOG },
{ L("PENDING"), TRUNK_REQUEST_STATE_PENDING },
{ L("PARTIAL"), TRUNK_REQUEST_STATE_PARTIAL },
{ L("REAPABLE"), TRUNK_REQUEST_STATE_REAPABLE },
{ L("COMPLETE"), TRUNK_REQUEST_STATE_COMPLETE },
{ L("FAILED"), TRUNK_REQUEST_STATE_FAILED },
{ L("CANCEL"), TRUNK_REQUEST_STATE_CANCEL },
{ L("CANCEL-SENT"), TRUNK_REQUEST_STATE_CANCEL_SENT },
{ L("CANCEL-PARTIAL"), TRUNK_REQUEST_STATE_CANCEL_PARTIAL },
{ L("CANCEL-COMPLETE"), TRUNK_REQUEST_STATE_CANCEL_COMPLETE }
}

Definition at line 357 of file trunk.c.

◆ trunk_request_states_len

size_t trunk_request_states_len = NUM_ELEMENTS(trunk_request_states)
static

Definition at line 372 of file trunk.c.

◆ trunk_states

fr_table_num_ordered_t const trunk_states[]
static
Initial value:
= {
{ L("IDLE"), TRUNK_STATE_IDLE },
{ L("ACTIVE"), TRUNK_STATE_ACTIVE },
{ L("PENDING"), TRUNK_STATE_PENDING }
}
@ TRUNK_STATE_PENDING
Trunk has connections, but none are active.
Definition: trunk.h:65
@ TRUNK_STATE_ACTIVE
Trunk has active connections.
Definition: trunk.h:64
@ TRUNK_STATE_IDLE
Trunk has no connections.
Definition: trunk.h:63

Definition at line 392 of file trunk.c.

◆ trunk_states_len

size_t trunk_states_len = NUM_ELEMENTS(trunk_states)
static

Definition at line 397 of file trunk.c.