diff --git a/include/haproxy/sink-t.h b/include/haproxy/sink-t.h index f72a4e12a..a9db336f1 100644 --- a/include/haproxy/sink-t.h +++ b/include/haproxy/sink-t.h @@ -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 diff --git a/src/sink.c b/src/sink.c index 25d7a2fee..a12fe51d4 100644 --- a/src/sink.c +++ b/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; }