[PR #5185] [management] Add heartbeat to Job endpoint to prevent proxy timeouts #25194

Open
opened 2026-08-05 06:09:40 -04:00 by saavagebueno · 0 comments
Owner

Original Pull Request: https://github.com/netbirdio/netbird/pull/5185

State: open
Merged: No


Summary

  • Add 30-second heartbeat to the /management.ManagementService/Job streaming endpoint to keep connections alive through reverse proxies

Problem

The Job streaming endpoint blocks indefinitely when there are no pending jobs, causing reverse proxies (Traefik, Cloudflare, Nginx) to timeout the connection after their idle timeout period (typically 60-120 seconds).

While the gRPC server has keepalive configured (HTTP/2 PING frames), reverse proxies measure idle time based on HTTP/2 DATA frames, not PING frames. This causes 504 Gateway Timeout errors for self-hosted deployments behind proxies.

Solution

Add a periodic heartbeat (every 30 seconds) that sends an empty JobRequest to keep the stream active. The client already handles empty messages gracefully — it logs "received unknown or empty job request, skipping" and continues.

Changes

  • management/server/job/channel.go: Add EventChan() method to expose channel for select
  • management/internals/shared/grpc/server.go: Modify sendJobsLoop to use ticker + add sendHeartbeat method

Test plan

  • Verified build passes
  • Tested with Traefik proxy (timeout issue resolved)
  • Run existing tests

Fixes #5184

Summary by CodeRabbit

  • New Features

    • Periodic heartbeat messaging added to keep job streams active and reduce unexpected disconnects.
    • Streaming loop upgraded for more responsive, event-driven job delivery.
    • Exposed a read-only events channel for safer integration with select-based consumers.
  • Bug Fixes

    • Improved error handling and connection lifecycle control for more reliable job delivery.

✏️ Tip: You can customize this high-level summary in your review settings.

**Original Pull Request:** https://github.com/netbirdio/netbird/pull/5185 **State:** open **Merged:** No --- ## Summary - Add 30-second heartbeat to the `/management.ManagementService/Job` streaming endpoint to keep connections alive through reverse proxies ## Problem The Job streaming endpoint blocks indefinitely when there are no pending jobs, causing reverse proxies (Traefik, Cloudflare, Nginx) to timeout the connection after their idle timeout period (typically 60-120 seconds). While the gRPC server has keepalive configured (HTTP/2 PING frames), reverse proxies measure idle time based on HTTP/2 DATA frames, not PING frames. This causes **504 Gateway Timeout** errors for self-hosted deployments behind proxies. ## Solution Add a periodic heartbeat (every 30 seconds) that sends an empty `JobRequest` to keep the stream active. The client already handles empty messages gracefully — it logs "received unknown or empty job request, skipping" and continues. ## Changes - `management/server/job/channel.go`: Add `EventChan()` method to expose channel for select - `management/internals/shared/grpc/server.go`: Modify `sendJobsLoop` to use ticker + add `sendHeartbeat` method ## Test plan - [x] Verified build passes - [x] Tested with Traefik proxy (timeout issue resolved) - [ ] Run existing tests Fixes #5184 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Periodic heartbeat messaging added to keep job streams active and reduce unexpected disconnects. * Streaming loop upgraded for more responsive, event-driven job delivery. * Exposed a read-only events channel for safer integration with select-based consumers. * **Bug Fixes** * Improved error handling and connection lifecycle control for more reliable job delivery. <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
saavagebueno added the pull-request label 2026-08-05 06:09:40 -04:00
Sign in to join this conversation.
No Label pull-request
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: DYNR/netbird#25194