From 4301b444164fddf9b1095de2388ef8f010da3c7f Mon Sep 17 00:00:00 2001 From: christophe-duc Date: Fri, 9 Jan 2026 14:31:23 -0400 Subject: [PATCH] fixed the refresh issue that appeared --- pkg/commands/runtime_libpod.go | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/pkg/commands/runtime_libpod.go b/pkg/commands/runtime_libpod.go index 0e42f8a9..fcdd0185 100644 --- a/pkg/commands/runtime_libpod.go +++ b/pkg/commands/runtime_libpod.go @@ -506,7 +506,8 @@ func (r *LibpodRuntime) RemovePod(ctx context.Context, id string, force bool) er } // Events streams container runtime events using native libpod event streaming. -// This provides real-time event delivery with <100ms latency instead of polling. +// This provides real-time event delivery with <100ms latency for actual events, +// plus an initial synthetic event to trigger UI load and periodic heartbeat refreshes. func (r *LibpodRuntime) Events(ctx context.Context) (<-chan Event, <-chan error) { eventChan := make(chan Event) errChan := make(chan error, 1) @@ -515,6 +516,18 @@ func (r *LibpodRuntime) Events(ctx context.Context) (<-chan Event, <-chan error) defer close(eventChan) defer close(errChan) + // Send initial synthetic event immediately to trigger UI load + // This ensures the UI displays containers/pods even before any real events occur + select { + case eventChan <- Event{ + Type: "system", + Action: "refresh", + Time: time.Now().Unix(), + }: + case <-ctx.Done(): + return + } + // Create libpod event channel (buffered to prevent blocking during bursts) libpodEventChan := make(chan events.ReadResult, 10) @@ -539,12 +552,31 @@ func (r *LibpodRuntime) Events(ctx context.Context) (<-chan Event, <-chan error) } }() + // Periodic heartbeat ticker for UI refresh when no events occur + // This is much less frequent than the old 2-second polling (now 10 seconds) + // because real events provide immediate updates + ticker := time.NewTicker(10 * time.Second) + defer ticker.Stop() + // Convert libpod events to ContainerRuntime Event format for { select { case <-ctx.Done(): return + case <-ticker.C: + // Send periodic heartbeat to ensure UI updates even without real events + // This handles edge cases like containers dying without generating events + select { + case eventChan <- Event{ + Type: "system", + Action: "refresh", + Time: time.Now().Unix(), + }: + case <-ctx.Done(): + return + } + case result, ok := <-libpodEventChan: if !ok { // Channel closed, exit