Skip to content

Add heartbeats to StreamBuildEvents wait-for-log-file loop#176

Open
hiroTamada wants to merge 1 commit intomainfrom
hiro/stream-build-heartbeats
Open

Add heartbeats to StreamBuildEvents wait-for-log-file loop#176
hiroTamada wants to merge 1 commit intomainfrom
hiro/stream-build-heartbeats

Conversation

@hiroTamada
Copy link
Copy Markdown
Contributor

@hiroTamada hiroTamada commented Mar 30, 2026

Summary

  • Adds a 15-second heartbeat ticker to the StreamBuildEvents wait-for-log-file loop
  • When a build is queued behind others, the SSE stream previously sent no events while waiting for the log file to appear. Infrastructure proxies (e.g. Railway) terminate idle SSE connections after ~60 seconds, causing the Kernel API to report "build timed out" even though the build hasn't started yet.
  • The heartbeat keeps the connection alive through the queue wait. The existing 30-second heartbeat in the main streaming loop already handles the active-build case.

Context

During a bulk migration of Unikraft deployments to Hypeman, builds queued behind others consistently timed out after exactly 60 seconds. Root cause: the SSE stream was idle during the queue wait, triggering an infrastructure idle timeout.

Test plan

  • Deploy to a staging Hypeman host
  • Submit multiple builds concurrently (more than max_concurrent_source_builds) to force queuing
  • Verify that queued builds receive heartbeat events and complete successfully instead of timing out

Made with Cursor


Note

Low Risk
Low risk, localized change to StreamBuildEvents that only adds periodic heartbeat events during the pre-log wait; main behavioral risk is extra event traffic or unexpected client handling of heartbeat events.

Overview
Prevents idle timeouts for queued builds by emitting heartbeat events while StreamBuildEvents is waiting for the build log file to appear.

This adds a 15s ticker in the wait-for-log-file loop (before tail starts) so SSE clients keep receiving events until logs begin streaming or the build reaches a terminal status.

Written by Cursor Bugbot for commit bffcd3e. This will update automatically on new commits. Configure here.

When a build is queued, StreamBuildEvents waits for the log file to
appear before streaming logs. During this wait, no events are sent on
the SSE connection. Infrastructure proxies (e.g. Railway) terminate
idle SSE connections after ~60 seconds, causing the Kernel API to see
a "build timed out" error even though the build hasn't started yet.

Add a 15-second heartbeat ticker to keep the SSE connection alive
while waiting for the log file. The existing 30-second heartbeat in
the main streaming loop already handles the active-build case.

Made-with: Cursor
Comment on lines +1150 to +1154
select {
case out <- BuildEvent{Type: EventTypeHeartbeat, Timestamp: time.Now()}:
case <-ctx.Done():
return
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inner select seems redundant relative to the outer but nbd

}
break
}
waitHeartbeat.Stop()
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't need? ✂️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants