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
goto out_close;
appctx->svcctx = (void *)sft;
appctx_wakeup(appctx);
+ sft->last_conn = now_ms;
return appctx;
/* Error unrolling */
* 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;
}