MEDIUM: peers: Save date of the last update to wake the peer applet

Instead of looking for new updates in each updates lists to wake a peer
applet up, we now only detect that some updates should have been inserted by
comparing the date of the last update inserted in the list and the last
update sent to the peer.

It is not 100% accurrate of course. Some extra wakeups may be observed. But
this should not lead to any spinning loop because the operation is performed
by the sync task. This task is woken up when a timeout is fired or when an
update was inserted. However, this saves several loops on the updates lists.
This commit is contained in:
Christopher Faulet 2025-10-14 14:02:05 +02:00
parent adf6a167a4
commit 922a1d4e3a
4 changed files with 8 additions and 23 deletions

View File

@ -164,6 +164,7 @@ struct peer {
unsigned int heartbeat; /* next heartbeat timer */
unsigned int confirm; /* confirm message counter */
unsigned int last_hdshk; /* Date of the last handshake. */
unsigned int last_update; /* Date of last update sent */
uint32_t rx_hbt; /* received heartbeats counter */
uint32_t tx_hbt; /* transmitted heartbeats counter */
uint32_t no_hbt; /* no received heartbeat counter */

View File

@ -230,7 +230,7 @@ struct stktable {
__decl_thread(HA_RWLOCK_T lock); /* lock related to the table */
THREAD_ALIGN(64);
unsigned int last_update; /* Date of the last update inserted in the list */
struct mt_list updates; /* list of sticky updates sequence */
struct mt_list *pend_updts; /* list of updates to be added to the update sequence list, one per thread-group */
struct tasklet *updt_task;/* tasklet responsible for pushing the pending updates into the tree */

View File

@ -1634,6 +1634,7 @@ int peer_send_teachmsgs(struct appctx *appctx, struct peer *p, struct shared_tab
p->last.id = st->update_id;
st->update_id++;
p->flags &= ~PEER_F_SYNCHED;
p->last_update = now_ms;
/* identifier may not needed in next update message */
new_pushed = 0;
@ -3521,18 +3522,9 @@ static void __process_running_peer_sync(struct task *task, struct peers *peers,
/* Awake session if there is data to push */
for (st = peer->tables; st ; st = st->next) {
struct stksess *ts;
struct mt_list back;
if (tick_is_le(peer->last_update, st->table->last_update))
update_to_push = 1;
// TODO: may be handled via an atomic flags ?
MT_LIST_FOR_EACH_ENTRY_LOCKED(ts, &st->last->upd, upd, back) {
if (&ts->upd == &st->table->updates)
break;
if (&ts->upd != &st->table->updates && ts->updt_type == STKSESS_UPDT_LOCAL) {
update_to_push = 1;
break;
}
}
if (update_to_push == 1) {
/* wake up the peer handler to push local updates */
/* There is no need to send a heartbeat message
@ -3721,17 +3713,7 @@ static void __process_stopping_peer_sync(struct task *task, struct peers *peers,
/* current peer connection is active and established
* wake up all peer handlers to push remaining local updates */
for (st = peer->tables; st ; st = st->next) {
struct stksess *ts;
struct mt_list back;
int wakeup = 0;
MT_LIST_FOR_EACH_ENTRY_LOCKED(ts, &st->last->upd, upd, back) {
if (&ts->upd != &st->table->updates && ts->updt_type == STKSESS_UPDT_LOCAL) {
wakeup = 1;
break;
}
}
if (wakeup) {
if (tick_is_le(peer->last_update, st->table->last_update)) {
appctx_wakeup(peer->appctx);
break;
}

View File

@ -840,6 +840,7 @@ struct task *stktable_add_pend_updates(struct task *t, void *ctx, unsigned int s
if (i > 0) {
/* We did at least one update, let's wake the sync task */
table->last_update = now_ms;
task_wakeup(table->sync_task, TASK_WOKEN_MSG);
}
return t;
@ -1125,6 +1126,7 @@ int stktable_init(struct stktable *t, char **err_msg)
for (i = 0; i < global.nbtgroups; i++)
MT_LIST_INIT(&t->pend_updts[i]);
t->updt_task = tasklet_new();
t->last_update = TICK_ETERNITY;
if (!t->updt_task)
goto mem_error;
t->updt_task->context = t;