mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-06 23:27:04 +02:00
BUG/MINOR: sink: add tempo between 2 connection attempts for sft servers
When the connection for sink_forward_{oc}_applet fails or a previous one is destroyed, the sft->appctx is instantly released. However process_sink_forward_task(), which may run at any time, iterates over all known sfts and tries to create sessions for orphan ones. It means that instantly after sft->appctx is destroyed, a new one will be created, thus a new connection attempt will be made. It can be an issue with tcp log-servers or sink servers, because if the server is unavailable, process_sink_forward() will keep looping without any temporisation until the applet survives (ie: connection succeeds), which results in unexpected CPU usage on the threads responsible for that task. Instead, we add a tempo logic so that a delay of 1second is applied between two retries. Of course the initial attempt is not delayed. This could be backported to all stable versions.
This commit is contained in:
parent
c9d4192726
commit
9561b9fb69
@ -40,6 +40,7 @@ enum sink_type {
|
||||
struct sink_forward_target {
|
||||
struct server *srv; // used server
|
||||
struct appctx *appctx; // appctx of current session
|
||||
uint last_conn; // copy of now_ms for last session establishment attempt
|
||||
size_t ofs; // ring buffer reader offset
|
||||
size_t e_processed; // processed events
|
||||
struct sink *sink; // the associated sink
|
||||
|
16
src/sink.c
16
src/sink.c
@ -654,6 +654,7 @@ static struct appctx *sink_forward_session_create(struct sink *sink, struct sink
|
||||
goto out_close;
|
||||
appctx->svcctx = (void *)sft;
|
||||
appctx_wakeup(appctx);
|
||||
sft->last_conn = now_ms;
|
||||
return appctx;
|
||||
|
||||
/* Error unrolling */
|
||||
@ -678,9 +679,20 @@ static struct task *process_sink_forward(struct task * task, void *context, unsi
|
||||
* assigment right away since the applet is not supposed to change
|
||||
* during the session lifetime. By doing the assignment now we
|
||||
* make sure to start the session exactly once.
|
||||
*
|
||||
* We enforce a tempo to ensure we don't perform more than 1 session
|
||||
* establishment attempt per second.
|
||||
*/
|
||||
if (!sft->appctx)
|
||||
sft->appctx = sink_forward_session_create(sink, sft);
|
||||
if (!sft->appctx) {
|
||||
uint tempo = sft->last_conn + MS_TO_TICKS(1000);
|
||||
|
||||
if (sft->last_conn == TICK_ETERNITY || tick_is_expired(tempo, now_ms))
|
||||
sft->appctx = sink_forward_session_create(sink, sft);
|
||||
else if (task->expire == TICK_ETERNITY)
|
||||
task->expire = tempo;
|
||||
else
|
||||
task->expire = tick_first(task->expire, tempo);
|
||||
}
|
||||
HA_SPIN_UNLOCK(SFT_LOCK, &sft->lock);
|
||||
sft = sft->next;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user