fr_event_list_t *el; //!< Event list used by this trunk and the connection.
- fr_trunk_conf_t const *conf; //!< Trunk common configuration.
+ fr_trunk_conf_t conf; //!< Trunk common configuration.
fr_dlist_head_t unassigned; //!< Requests in the unassigned state. Waiting to be
///< enqueued.
DEBUG4("Calling connection_alloc(tconn=%p, el=%p, log_prefix=\"%s\", uctx=%p)", \
(_tconn), (_tconn)->trunk->el, trunk->log_prefix, (_tconn)->trunk->uctx); \
(_tconn)->trunk->in_handler = (void *) (_tconn)->trunk->funcs.connection_alloc; \
- (_tconn)->conn = trunk->funcs.connection_alloc((_tconn), (_tconn)->trunk->el, (_tconn)->trunk->conf->connect_timeout, (_tconn)->trunk->conf->reconnect_delay, (_tconn)->trunk->log_prefix, trunk->uctx); \
+ (_tconn)->conn = trunk->funcs.connection_alloc((_tconn), (_tconn)->trunk->el, (_tconn)->trunk->conf.connect_timeout, (_tconn)->trunk->conf.reconnect_delay, (_tconn)->trunk->log_prefix, trunk->uctx); \
(_tconn)->trunk->in_handler = prev; \
if (!(_tconn)->conn) { \
ERROR("Failed creating new connection"); \
/*
* Enforces max_uses
*/
- if ((trunk->conf->max_uses > 0) && (tconn->sent_count >= trunk->conf->max_uses)) {
+ if ((trunk->conf.max_uses > 0) && (tconn->sent_count >= trunk->conf.max_uses)) {
trunk_connection_enter_draining_to_free(tconn);
}
* number of connections, and maximum
* number of requests per connection.
*/
- if (trunk->conf->max_req_per_conn > 0) {
+ if (trunk->conf.max_req_per_conn > 0) {
uint64_t total_reqs;
total_reqs = fr_trunk_request_count_by_state(trunk, FR_TRUNK_CONN_ALL, FR_TRUNK_REQUEST_ALL) + 1;
- limit = trunk->conf->max * (uint64_t)trunk->conf->max_req_per_conn;
+ limit = trunk->conf.max * (uint64_t)trunk->conf.max_req_per_conn;
if ((limit > 0) && (total_reqs > limit)) {
ROPTIONAL(RWARN, WARN, "Refusing to enqueue requests - "
"Limit of %"PRIu64" requests reached", limit);
switch (rcode) {
case FR_TRUNK_ENQUEUE_OK:
trunk_request_enter_pending(treq, tconn);
- if (trunk->conf->always_writable) trunk_connection_writable(tconn);
+ if (trunk->conf.always_writable) trunk_connection_writable(tconn);
break;
case FR_TRUNK_ENQUEUE_IN_BACKLOG:
trunk->req_alloc_reused++;
} else {
MEM(treq = talloc_pooled_object(trunk, fr_trunk_request_t,
- trunk->conf->req_pool_headers, trunk->conf->req_pool_size));
+ trunk->conf.req_pool_headers, trunk->conf.req_pool_size));
talloc_set_destructor(treq, _trunk_request_free);
treq->state = FR_TRUNK_REQUEST_UNASSIGNED;
treq->trunk = trunk;
treq->preq = preq;
treq->rctx = rctx;
trunk_request_enter_pending(treq, tconn);
- if (trunk->conf->always_writable) trunk_connection_writable(tconn);
+ if (trunk->conf.always_writable) trunk_connection_writable(tconn);
break;
case FR_TRUNK_ENQUEUE_IN_BACKLOG:
/*
* Enforces max_req_per_conn
*/
- if (trunk->conf->max_req_per_conn > 0) {
+ if (trunk->conf.max_req_per_conn > 0) {
count = fr_trunk_request_count_by_connection(tconn, FR_TRUNK_REQUEST_ALL);
- if (count >= trunk->conf->max_req_per_conn) trunk_connection_enter_inactive(tconn);
+ if (count >= trunk->conf.max_req_per_conn) trunk_connection_enter_inactive(tconn);
}
}
* Enforces max_req_per_conn
*/
count = fr_trunk_request_count_by_connection(tconn, FR_TRUNK_REQUEST_ALL);
- if ((trunk->conf->max_req_per_conn == 0) || (count < trunk->conf->max_req_per_conn)) {
+ if ((trunk->conf.max_req_per_conn == 0) || (count < trunk->conf.max_req_per_conn)) {
trunk_connection_enter_active(tconn);
}
}
* If the connection is always writable,
* then we don't care about write events.
*/
- if (!trunk->conf->always_writable &&
+ if (!trunk->conf.always_writable &&
fr_trunk_request_count_by_connection(tconn,
FR_TRUNK_REQUEST_PARTIAL |
FR_TRUNK_REQUEST_PENDING |
* Insert a timer to reconnect the
* connection periodically.
*/
- if (trunk->conf->lifetime > 0) {
+ if (trunk->conf.lifetime > 0) {
(void)fr_event_timer_in(tconn, trunk->el, &tconn->lifetime_ev,
- trunk->conf->lifetime, _trunk_connection_lifetime_expire, tconn);
+ trunk->conf.lifetime, _trunk_connection_lifetime_expire, tconn);
}
}
/*
* Remove the reconnect event
*/
- if (trunk->conf->lifetime > 0) fr_event_timer_delete(trunk->el, &tconn->lifetime_ev);
}
/** Give the trunk API an opportunity to free the connection if it closes
* Something wanted the connection freed when it finally closed...
*/
if (tconn->free_on_close) talloc_free(tconn);
+ if (trunk->conf.lifetime > 0) fr_event_timer_delete(trunk->el, &tconn->lifetime_ev);
}
/** Connection failed to connect before it was connected
* have been idle for too long.
*/
while ((treq = fr_dlist_tail(&trunk->unassigned)) &&
- ((treq->last_freed + trunk->conf->req_cleanup_delay) <= now)) talloc_free(treq);
+ ((treq->last_freed + trunk->conf.req_cleanup_delay) <= now)) talloc_free(treq);
/*
* We're above the target requests per connection
* spawn more connections!
*/
if ((trunk->last_above_target >= trunk->last_below_target)) {
- if ((trunk->last_above_target + trunk->conf->open_delay) > now) {
+ if ((trunk->last_above_target + trunk->conf.open_delay) > now) {
DEBUG4("Not opening connection - Need to be above target for %pVs. It's been %pVs",
- fr_box_time_delta(trunk->conf->open_delay),
+ fr_box_time_delta(trunk->conf.open_delay),
fr_box_time_delta(now - trunk->last_above_target));
goto done; /* too soon */
}
* connections to active before spawning
* any new connections.
*/
- if ((trunk->conf->max > 0) && (conn_count >= trunk->conf->max)) {
+ if ((trunk->conf.max > 0) && (conn_count >= trunk->conf.max)) {
DEBUG4("Not opening connection - Have %u connections, need %u or below",
- conn_count, trunk->conf->max);
+ conn_count, trunk->conf.max);
goto done;
}
*/
if (conn_count > 0) {
average = DIVIDE_CEIL(req_count, (conn_count + 1));
- if (average < trunk->conf->target_req_per_conn) {
+ if (average < trunk->conf.target_req_per_conn) {
DEBUG4("Not opening connection - Would leave us below our target requests "
"per connection (now %u, after open %u)",
DIVIDE_CEIL(req_count, conn_count), average);
* Implement delay if there's no connections that
* could be immediately re-activated.
*/
- if ((trunk->last_open + trunk->conf->open_delay) > now) {
+ if ((trunk->last_open + trunk->conf.open_delay) > now) {
DEBUG4("Not opening connection - Need to wait %pVs before opening another connection. "
"It's been %pVs",
- fr_box_time_delta(trunk->conf->open_delay),
+ fr_box_time_delta(trunk->conf.open_delay),
fr_box_time_delta(now - trunk->last_open));
goto done;
}
DEBUG4("Opening connection - Above target requests per connection (now %u, target %u)",
- DIVIDE_CEIL(req_count, conn_count), trunk->conf->target_req_per_conn);
+ DIVIDE_CEIL(req_count, conn_count), trunk->conf.target_req_per_conn);
/* last_open set by trunk_connection_spawn */
(void)trunk_connection_spawn(trunk, now);
goto done;
* Free some connections...
*/
if (trunk->last_below_target > trunk->last_above_target) {
- if ((trunk->last_below_target + trunk->conf->close_delay) > now) {
+ if ((trunk->last_below_target + trunk->conf.close_delay) > now) {
DEBUG4("Not closing connection - Need to be below target for %pVs. It's been %pVs",
- fr_box_time_delta(trunk->conf->close_delay),
+ fr_box_time_delta(trunk->conf.close_delay),
fr_box_time_delta(now - trunk->last_below_target));
goto done; /* too soon */
}
goto close;
}
- if ((trunk->conf->min > 0) && ((conn_count - 1) < trunk->conf->min)) {
+ if ((trunk->conf.min > 0) && ((conn_count - 1) < trunk->conf.min)) {
DEBUG4("Not closing connection - Have %u connections, need %u or above",
- conn_count, trunk->conf->min);
+ conn_count, trunk->conf.min);
goto done;
}
* will that take us above our target threshold.
*/
average = DIVIDE_CEIL(req_count, (conn_count - 1));
- if (average > trunk->conf->target_req_per_conn) {
+ if (average > trunk->conf.target_req_per_conn) {
DEBUG4("Not closing connection - Would leave us above our target requests per connection "
"(now %u, after close %u)", DIVIDE_CEIL(req_count, conn_count), average);
goto done;
}
DEBUG4("Closing connection - Below target requests per connection (now %u, target %u)",
- DIVIDE_CEIL(req_count, conn_count), trunk->conf->target_req_per_conn);
+ DIVIDE_CEIL(req_count, conn_count), trunk->conf.target_req_per_conn);
close:
- if ((trunk->last_closed + trunk->conf->close_delay) > now) {
+ if ((trunk->last_closed + trunk->conf.close_delay) > now) {
DEBUG4("Not closing connection - Need to wait %pVs before closing another connection. "
"It's been %pVs",
- fr_box_time_delta(trunk->conf->close_delay),
+ fr_box_time_delta(trunk->conf.close_delay),
fr_box_time_delta(now - trunk->last_closed));
goto done;
}
fr_trunk_t *trunk = talloc_get_type_abort(uctx, fr_trunk_t);
trunk_manage(trunk, now, __FUNCTION__);
- fr_event_timer_in(trunk, el, &trunk->manage_ev, trunk->conf->manage_interval,
+ fr_event_timer_in(trunk, el, &trunk->manage_ev, trunk->conf.manage_interval,
_trunk_timer, trunk);
}
* No connections, but we do have requests
*/
if (conn_count == 0) {
- if ((req_count > 0) && (trunk->conf->target_req_per_conn > 0)) goto above_target;
+ if ((req_count > 0) && (trunk->conf.target_req_per_conn > 0)) goto above_target;
goto done;
}
if (req_count == 0) {
- if (trunk->conf->target_req_per_conn > 0) goto below_target;
+ if (trunk->conf.target_req_per_conn > 0) goto below_target;
goto done;
}
* Calculate the average
*/
average = DIVIDE_CEIL(req_count, conn_count);
- if (average > trunk->conf->target_req_per_conn) {
+ if (average > trunk->conf.target_req_per_conn) {
above_target:
/*
* Edge - Below target to above target (too many requests per conn - spawn more)
*/
if (trunk->last_above_target <= trunk->last_below_target) trunk->last_above_target = now;
- } else if (average < trunk->conf->target_req_per_conn) {
+ } else if (average < trunk->conf.target_req_per_conn) {
below_target:
/*
* Edge - Above target to below target (too few requests per conn - close some)
/*
* Spawn the initial set of connections
*/
- for (i = 0; i < trunk->conf->start; i++) {
+ for (i = 0; i < trunk->conf.start; i++) {
if (trunk_connection_spawn(trunk, fr_time()) != 0) return -1;
}
* Insert the event timer to manage
* the interval between managing connections.
*/
- if (trunk->conf->manage_interval > 0) {
- fr_event_timer_in(trunk, trunk->el, &trunk->manage_ev, trunk->conf->manage_interval,
+ if (trunk->conf.manage_interval > 0) {
+ fr_event_timer_in(trunk, trunk->el, &trunk->manage_ev, trunk->conf.manage_interval,
_trunk_timer, trunk);
}
*/
static int _trunk_free(fr_trunk_t *trunk)
{
- fr_connection_t *tconn;
+ fr_trunk_connection_t *tconn;
fr_trunk_request_t *treq;
DEBUG4("Trunk free %p", trunk);
MEM(trunk = talloc_zero(ctx, fr_trunk_t));
trunk->el = el;
trunk->log_prefix = talloc_strdup(trunk, log_prefix);
- trunk->conf = conf;
-
+ memcpy(&trunk->conf, conf, sizeof(trunk->conf));
memcpy(&trunk->funcs, funcs, sizeof(trunk->funcs));
if (!trunk->funcs.connection_prioritise) {
trunk->funcs.connection_prioritise = _trunk_connection_order_by_shortest_queue;