|
|
|
|
@ -45,7 +45,11 @@ struct ETCP_LINK* etcp_loadbalancer_select_link(struct ETCP_CONN* etcp) {
|
|
|
|
|
// link_index, link, link->initialized, link->shaper_timer==NULL?1:0,
|
|
|
|
|
// (unsigned long long)link->shaper_load_time_tb, (unsigned long long)link->shaper_sub_nanotime);
|
|
|
|
|
|
|
|
|
|
if (!link->initialized || link->shaper_timer || link->link_status != 1) {// если установлен таймер - значит надо ждать. не рассматриваем этот линк
|
|
|
|
|
if (!link->initialized || link->link_status != 1) { |
|
|
|
|
link = link->next; |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
if (loadbalancer_link_can_send(link) == 0) { |
|
|
|
|
link = link->next; |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
@ -144,22 +148,38 @@ void etcp_loadbalancer_send(struct ETCP_DGRAM* dgram) {
|
|
|
|
|
memory_pool_free(etcp->instance->pkt_pool, dgram); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// New: Notify when link is ready (called from timer or external)
|
|
|
|
|
int loadbalancer_link_can_send(struct ETCP_LINK* link) { |
|
|
|
|
if (!link) return 0; |
|
|
|
|
int can = 1; |
|
|
|
|
if (link->inflight_bytes >= link->inflight_lim_bytes) { |
|
|
|
|
link->send_blocked_inflight = 1; |
|
|
|
|
can = 0; |
|
|
|
|
} else { |
|
|
|
|
link->send_blocked_inflight = 0; |
|
|
|
|
} |
|
|
|
|
if (link->shaper_timer) { |
|
|
|
|
link->send_blocked_bandwidth = 1; |
|
|
|
|
can = 0; |
|
|
|
|
} else { |
|
|
|
|
link->send_blocked_bandwidth = 0; |
|
|
|
|
} |
|
|
|
|
return can; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void loadbalancer_link_ready(struct ETCP_LINK* link) { |
|
|
|
|
if (!link || !link->etcp) { |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_ETCP, "loadbalancer_link_ready: invalid link (%p)", link); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (loadbalancer_link_can_send(link) == 0) { |
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "loadbalancer_link_ready: link still blocked"); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "loadbalancer_link_ready: link=%p now ready, notifying ETCP_CONN", link); |
|
|
|
|
|
|
|
|
|
// Call ETCP_CONN resume (assumes link_ready_for_send_fn in ETCP_CONN; add to etcp.h: void (*link_ready_for_send_fn)(struct ETCP_CONN*);)
|
|
|
|
|
if (link->etcp->link_ready_for_send_fn) { |
|
|
|
|
link->etcp->link_ready_for_send_fn(link->etcp); |
|
|
|
|
} else { |
|
|
|
|
// Fallback: request next packet (implement etcp_request_pkt in etcp.c if needed)
|
|
|
|
|
// etcp_request_pkt(link->etcp);
|
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_ETCP, "loadbalancer_link_ready: no link_ready_for_send_fn set, skipping notify"); |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_ETCP, "loadbalancer_link_ready: no link_ready_for_send_fn set"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|