@@ -194,17 +194,6 @@ func (h *eventHandlerImpl) HandleEventBatch(ctx context.Context, batch events.Ev
194194 }
195195 haproxyConfDiffs := h .haproxyConfBuilder .GetDiffs ()
196196 h .recordDiffMetrics (haproxyConfDiffs )
197- if ! haproxyConfDiffs .IsEmpty () || haproxyConfDiffs .ReloadNeed {
198- if h .config .TransferHaproxyConfChannel != nil {
199- h .logger .LogAttrs (context .Background (), slog .LevelInfo , "DIFFS CONTROLLER => HUG" )
200- haproxyConfDiffs .Done = make (chan struct {})
201- transferStart := time .Now ()
202- h .config .TransferHaproxyConfChannel <- haproxyConfDiffs
203- <- haproxyConfDiffs .Done
204- metrics .ConfigTransferDuration .Observe (time .Since (transferStart ).Seconds ())
205- h .logger .LogAttrs (context .Background (), slog .LevelInfo , "DIFFS HUG => CONTROLLER" )
206- }
207- }
208197
209198 // -------------
210199 // Status updates
@@ -218,6 +207,22 @@ func (h *eventHandlerImpl) HandleEventBatch(ctx context.Context, batch events.Ev
218207 // Now process them
219208 h .statusUpdater .UpdateStatus (ctx , statusUpdates )
220209
210+ if ! haproxyConfDiffs .IsEmpty () || haproxyConfDiffs .ReloadNeed {
211+ if h .config .TransferHaproxyConfChannel != nil {
212+ h .logger .LogAttrs (context .Background (), slog .LevelInfo , "[sending] CONTROLLER => HUG: DIFFS" )
213+ haproxyConfDiffs .Done = make (chan struct {})
214+ haproxyConfDiffs .ResultCh = make (chan diffs.HaproxyConfResult , 1 )
215+ transferStart := time .Now ()
216+ h .config .TransferHaproxyConfChannel <- haproxyConfDiffs
217+ h .waitDone (haproxyConfDiffs .Done )
218+ metrics .ConfigTransferDuration .Observe (time .Since (transferStart ).Seconds ())
219+ h .logger .LogAttrs (context .Background (), slog .LevelInfo , "[received] HUG => CONTROLLER: DIFFS (Done)" )
220+
221+ // Forward the HUG result back as status feedback to the relevant Gateway/Route objects.
222+ h .forwardFeedback (ctx , haproxyConfDiffs .ResultCh )
223+ }
224+ }
225+
221226 // Reconcile Hug service Ports
222227 h .hugServiceReconciler .ReconcilePorts (ctx , gatetree .VirtualListeners )
223228}
@@ -256,6 +261,50 @@ func (h *eventHandlerImpl) updateClusterStore(event any) {
256261 }
257262}
258263
264+ // waitDoneTimeout is the maximum time to wait for Done to be closed after
265+ // sending diffs to HUG.
266+ const waitDoneTimeout = 30 * time .Second
267+
268+ // waitDone blocks until done is closed or waitDoneTimeout elapses, logging a
269+ // warning in the latter case.
270+ func (h * eventHandlerImpl ) waitDone (done <- chan struct {}) {
271+ select {
272+ case <- done :
273+ case <- time .After (waitDoneTimeout ):
274+ h .logger .LogAttrs (context .Background (), slog .LevelWarn ,
275+ "timed out waiting for Done signal from HUG" ,
276+ )
277+ }
278+ }
279+
280+ // forwardFeedbackTimeout is the maximum time to wait for a result on ResultCh
281+ // after Done has been closed. The result may arrive slightly after Done in some
282+ // implementations, so we give a short grace period before giving up.
283+ const forwardFeedbackTimeout = 5 * time .Second
284+
285+ // forwardFeedback waits up to forwardFeedbackTimeout for a result on resultCh,
286+ // prepares the feedback status updates, and dispatches them through the shared
287+ // statusUpdater channel.
288+ func (h * eventHandlerImpl ) forwardFeedback (ctx context.Context , resultCh chan diffs.HaproxyConfResult ) {
289+ select {
290+ case result := <- resultCh :
291+ h .logger .LogAttrs (ctx , slog .LevelInfo , "[received] HUG => CONTROLLER: haproxy conf update result " , slog .Any ("result" , result ))
292+ gatetree := h .treeBuilder .GetTree ()
293+ for gwKey , gen := range result .GatewayObservedGenerations {
294+ gatetree .UpdateListenerProgrammedCondition (gwKey , gen , result .Err )
295+ }
296+ gateways := gatetree .RLockGateways ()
297+ updates := h .statusUpdater .PrepareFeedbackStatusUpdate (result , gateways )
298+ gatetree .RUnlockGateways ()
299+ h .statusUpdater .UpdateStatus (ctx , updates )
300+ case <- time .After (forwardFeedbackTimeout ):
301+ // TODO: check with the team
302+ h .logger .LogAttrs (context .Background (), slog .LevelWarn ,
303+ "timed out waiting for result from HUG on ResultCh" ,
304+ )
305+ }
306+ }
307+
259308func (* eventHandlerImpl ) recordDiffMetrics (d diffs.HaproxyConfDiffs ) {
260309 metrics .ConfigDiffs .WithLabelValues ("created" , "frontend" ).Add (float64 (len (d .Created .Frontends )))
261310 metrics .ConfigDiffs .WithLabelValues ("updated" , "frontend" ).Add (float64 (len (d .Updated .Frontends )))
0 commit comments