| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
…with configurable timeouts - Introduced `spawn_server_exec_timedwait` across spawn server implementations (POSIX, libuv, nofork, Windows). - Added timeout-based process cleanup for `POPEN_INSTANCE` via `spawn_popen_timedwait`. - Configurable notification execution timeout (`notification_execution_timeout_seconds`) added to health configuration. - Updated alert notification handling to kill hanging processes after exceeding the timeout. - Extended unit tests to validate timed-wait behavior for processes.
There was a problem hiding this comment.
2 issues found across 12 files
Confidence score: 2/5
sequenceDiagram
participant Health as Health Thread
participant AE as ALARM_ENTRY
participant SPopen as spawn_popen_timedwait()
participant SSExec as spawn_server_exec_timedwait()
participant Child as Notification Process
participant Config as netdata.conf
Note over Health,Config: Bound alert notification execution with configurable timeout
Health->>Config: CHANGED: read "notification execution timeout" (default 2m/120s)
Config-->>Health: timeout value (0 = wait forever)
Health->>AE: health_alarm_wait_for_execution(ae)
AE->>AE: CHANGED: compute deadline = exec_run_timestamp + timeout
loop every 1 second
AE->>SPopen: spawn_popen_timedwait(pi, 1000ms, &code)
SPopen->>SSExec: spawn_server_exec_timedwait(server, si, timeout_ms, &status)
SSExec->>Child: close pipe FDs, poll for exit
alt child exited within slice
Child-->>SSExec: exit status
SSExec-->>SPopen: SPAWN_TIMEDWAIT_EXITED, status
SPopen-->>AE: true, code
AE->>Health: notification completed
AE->>AE: break loop
else timeout expired (child still running)
SSExec-->>SPopen: SPAWN_TIMEDWAIT_RUNNING
SPopen-->>AE: false, pi still valid
end
end
alt timeout exceeded OR service shutting down
AE->>AE: CHANGED: check now_realtime_sec() >= deadline OR !service_running(SERVICE_HEALTH)
AE->>SPopen: spawn_popen_kill(pi, 0)
SPopen->>Child: force kill process
Child-->>SPopen: terminated
SPopen-->>AE: code = 128
AE->>Health: notification killed, continue evaluation
end
AE->>Health: CHANGED: health thread continues evaluation/shutdown immediately
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
Sorry, something went wrong.
There was a problem hiding this comment.
This PR prevents the Netdata health thread from hanging indefinitely on stuck alert notification processes by introducing timed-wait APIs in the spawn subsystem and enforcing a configurable notification execution timeout in health notification handling.
Changes:
Copilot reviewed 12 out of 12 changed files in this pull request and generated 5 comments.
Show a summary per file| File | Description |
|---|---|
| src/libnetdata/spawn_server/spawn-tester.c | Adds tests for timed-wait behavior (child exits vs. requires kill). |
| src/libnetdata/spawn_server/spawn_server.h | Introduces SPAWN_TIMEDWAIT_RESULT and the spawn_server_exec_timedwait() API. |
| src/libnetdata/spawn_server/spawn_server_windows.c | Implements timed-wait for Windows via WaitForSingleObject(). |
| src/libnetdata/spawn_server/spawn_server_posix.c | Implements timed-wait for POSIX via waitpid(..., WNOHANG) polling until deadline. |
| src/libnetdata/spawn_server/spawn_server_nofork.c | Implements timed-wait for nofork mode via socket wait with timeout. |
| src/libnetdata/spawn_server/spawn_server_libuv.c | Implements timed-wait for libuv mode via semaphore polling until deadline. |
| src/libnetdata/spawn_server/spawn_popen.h | Adds spawn_popen_timedwait() API documentation and signature. |
| src/libnetdata/spawn_server/spawn_popen.c | Implements spawn_popen_timedwait() on top of spawn-server timed-wait. |
| src/health/health.c | Adds and loads the new notification execution timeout config option (with validation). |
| src/health/health_notifications.c | Enforces bounded notification execution and kills notifications past deadline / during shutdown. |
| src/health/health_internals.h | Adds notification_execution_timeout_seconds to health globals config. |
| src/daemon/config/README.md | Documents the new [health] notification execution timeout setting. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Sorry, something went wrong.
…g processes - Clamp negative/zero timeouts to positive defaults to avoid infinite waits. - Escalate hanging child processes from SIGTERM to SIGKILL after timeout expiration. - Ensure consistent behavior across spawn server implementations (POSIX, libuv, nofork, Windows). - Refactor health notification timeout handling to avoid indefinite blocking by slow/hanging processes.
|
@cubic-dev-ai please review again |
Sorry, something went wrong.
@stelfrag I have started the AI code review. It will take a few minutes to complete. |
Sorry, something went wrong.
…ve timeout behavior - Updated comments to explain bounded timeout behavior (non-infinite waits) for child process management. - Normalized negative timeout values to effectively enable non-blocking polls. - Improved documentation on health notification timeout clamping.
… processes blocked on I/O.
There was a problem hiding this comment.
4 issues found across 12 files
Confidence score: 3/5
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
Sorry, something went wrong.
…ement - Updated comments to explain PID reuse prevention and bounded timeout behavior. - Enhanced documentation for timeout clamping and child process escalation (SIGKILL after SIGTERM). - Improved error handling for Windows process waits (reporting failed handles as running instead of exited).
- Updated `SPAWN_TIMEDWAIT_ERROR` handling to distinguish terminal errors from transient "still running" states. - Prevent looping on broken channels or handles to avoid infinite spins. - Refactored escalation logic for SIGKILL if process wait cannot be completed.
|
@cubic-dev-ai please review again |
Sorry, something went wrong.
@stelfrag I have started the AI code review. It will take a few minutes to complete. |
Sorry, something went wrong.
There was a problem hiding this comment.
1 issue found across 12 files
Confidence score: 4/5
sequenceDiagram
participant HealthThread as Health Thread
participant NotificationWait as health_alarm_wait_for_execution()
participant SpawnPopen as spawn_popen_timedwait()
participant SpawnServer as spawn_server_exec_timedwait()
participant ChildProcess as Notification Script
participant Config as Health Config
Note over HealthThread,Config: NEW: Configurable notification execution timeout (default 2m)
Config->>HealthThread: Load notification_execution_timeout_seconds (clamped)
HealthThread->>HealthThread: Run notification script (via spawn_popen_run)
HealthThread->>NotificationWait: Wait for notification to finish
NotificationWait->>NotificationWait: Get timeout from health_globals.config
NotificationWait->>NotificationWait: Compute monotonic deadline
loop Every 1s slice
NotificationWait->>SpawnPopen: spawn_popen_timedwait(pi, 1000, &code)
SpawnPopen->>SpawnPopen: Close child pipes
SpawnPopen->>SpawnServer: spawn_server_exec_timedwait(..., 1000, &status)
SpawnServer->>SpawnServer: Wait with timeout (backend-specific)
alt Child exited normally
SpawnServer-->>SpawnPopen: SPAWN_TIMEDWAIT_EXITED (status)
SpawnPopen->>SpawnPopen: Free instance, set code
SpawnPopen-->>NotificationWait: SPAWN_TIMEDWAIT_EXITED
NotificationWait->>NotificationWait: Break loop
else Child still running
SpawnServer-->>SpawnPopen: SPAWN_TIMEDWAIT_RUNNING
SpawnPopen-->>NotificationWait: SPAWN_TIMEDWAIT_RUNNING
NotificationWait->>NotificationWait: Check deadline and service_running()
alt Deadline reached or shutdown signalled
NotificationWait->>SpawnPopen: spawn_popen_kill(pi, 0)
SpawnPopen->>SpawnServer: spawn_server_exec_kill (SIGTERM→SIGKILL escalation)
SpawnServer->>ChildProcess: Send SIGTERM, then SIGKILL
SpawnServer-->>SpawnPopen: Wait completed (status)
SpawnPopen-->>NotificationWait: code = 128
NotificationWait->>NotificationWait: Break loop, log kill
else Still within deadline
NotificationWait->>NotificationWait: Continue loop (sleep until next slice)
end
else Status channel error (ERROR)
SpawnServer-->>SpawnPopen: SPAWN_TIMEDWAIT_ERROR
SpawnPopen-->>NotificationWait: SPAWN_TIMEDWAIT_ERROR
NotificationWait->>SpawnPopen: spawn_popen_kill (immediate)
Note over NotificationWait: ERROR is terminal – do not loop
end
end
NotificationWait-->>HealthThread: Notification finished (code)
HealthThread->>HealthThread: Continue health evaluation loop
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
Sorry, something went wrong.
…oss all implementations - Add null checks for `status` before assignment to enhance flexibility and prevent potential null pointer dereference. - Update logic in POSIX, libuv, nofork, and Windows implementations. - Improve documentation to clarify `status` as an optional parameter.
|
@cubic-dev-ai please review again |
Sorry, something went wrong.
@stelfrag I have started the AI code review. It will take a few minutes to complete. |
Sorry, something went wrong.
There was a problem hiding this comment.
2 issues found across 12 files
Confidence score: 3/5
sequenceDiagram
participant Health as Health Thread
participant Notif as Notification Queue
participant Popen as popen (libnetdata)
participant SpawnSrv as Spawn Server
participant ChildProc as Child Process (notification script)
participant Config as Config Store
Note over Health,Config: NEW: Bounded notification execution flow
Health->>Config: Read notification_execution_timeout_seconds
Config-->>Health: value (default 2m, 0=forever, clamped [0, INT32_MAX])
Health->>Notif: Pop next ALARM_ENTRY to wait for
Notif-->>Health: ae with popen_instance
loop Every 1s slice until child exits, shutdown, or deadline
Health->>Popen: spawn_popen_timedwait(pi, 1000ms, &code)
Popen->>Popen: Close child pipes (force EOF/exit)
Popen->>SpawnSrv: spawn_server_exec_timedwait(server, si, timeout_ms, &status)
alt Child Exited Normally
SpawnSrv->>SpawnSrv: Wait for process exit
SpawnSrv-->>Popen: SPAWN_TIMEDWAIT_EXITED + status
Popen->>Popen: freez(pi)
Popen-->>Health: SPAWN_TIMEDWAIT_EXITED, code
Health->>Health: Break loop, record exec_code
else Child Still Running
SpawnSrv-->>Popen: SPAWN_TIMEDWAIT_RUNNING
Popen-->>Health: SPAWN_TIMEDWAIT_RUNNING
Health->>Health: Check deadline_ut vs now_monotonic_usec()
Health->>Health: Check service_running(SERVICE_HEALTH)
opt Deadline Reached OR Shutdown Signal
Health->>Popen: spawn_popen_kill(pi, 0)
Popen->>Popen: Close pipes
Popen->>SpawnSrv: spawn_server_exec_kill(server, si, 0)
alt SIGTERM handled
SpawnSrv->>ChildProc: SIGTERM
SpawnSrv->>SpawnSrv: spawn_server_exec_timedwait(..., 2000ms)
alt Still alive after 2s
SpawnSrv->>ChildProc: SIGKILL (or equivalent)
end
else SIGTERM ignored or status channel broken
SpawnSrv->>ChildProc: SIGKILL (or equivalent)
end
SpawnSrv-->>Popen: status
Popen-->>Health: code = 128
Health->>Health: Break loop, record exec_code = 128
end
else Wait Error (broken status channel / handle)
SpawnSrv-->>Popen: SPAWN_TIMEDWAIT_ERROR
Popen-->>Health: SPAWN_TIMEDWAIT_ERROR
Health->>Health: Log error, treat as terminal
Health->>Popen: spawn_popen_kill(pi, 0) to reclaim
Health->>Health: Break loop, record exec_code = 128
end
end
Health->>Health: Set ae->popen_instance = NULL
Health->>Health: Store exec_code in ALARM_ENTRY
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
Sorry, something went wrong.
…s spawn server implementations - Added `SPAWN_KILL_DEFAULT_GRACE_MS` for consistent default grace periods on negative/zero timeouts. - Updated timeout calculations to ensure bounded termination waits before escalating from SIGTERM to SIGKILL. - Refactored logic in POSIX, libuv, and nofork implementations for clarity and consistency. - Improved error handling and cleanup in `spawn_popen_timedwait` to address terminal error scenarios.
|
@cubic-dev-ai please review again |
Sorry, something went wrong.
@stelfrag I have started the AI code review. It will take a few minutes to complete. |
Sorry, something went wrong.
There was a problem hiding this comment.
2 issues found across 13 files
Confidence score: 3/5
sequenceDiagram
participant Health as Health Plugin
participant Config as Health Config
participant Notif as Notification System
participant Spawn as Spawn Server
participant Child as Notification Child Process
participant Scheduler as Agent Scheduler
Note over Health,Child: CHANGED: Bounded notification execution
Health->>Config: Read notification_execution_timeout_seconds
Config-->>Health: 120s (default) or user-configured value
Health->>Notif: spawn_popen_run(alarm-notify.sh)
Notif->>Spawn: spawn_server_exec()
Spawn->>Child: fork/exec notification command
Child-->>Spawn: Running
Spawn-->>Notif: POPEN_INSTANCE
Notif-->>Health: ae with popen_instance
Note over Health,Spawn: NEW: Timed wait loop (1s slices)
loop Every HEALTH_NOTIFICATION_WAIT_SLICE_MS (1000ms)
Health->>Notif: spawn_popen_timedwait(pi, 1000ms, &code)
Notif->>Spawn: spawn_server_exec_timedwait(timeout_ms)
alt Child has exited
spawn_server_exec_timedwait ->> Child: Wait completed (EXITED)
Spawn-->>Notif: SPAWN_TIMEDWAIT_EXITED
Notif->>Notif: freez(pi), set code
Notif-->>Health: break loop
else Timeout expired, child still running
Spawn-->>Notif: SPAWN_TIMEDWAIT_RUNNING
Notif-->>Health: continue loop
else Status channel error (broken socket/handle)
Spawn-->>Notif: SPAWN_TIMEDWAIT_ERROR
Notif-->>Health: continue to kill logic
end
Health->>Health: Check if service_running(SERVICE_HEALTH)
Health->>Health: Check if deadline_reached (timeout > 0)
alt Shutdown requested or deadline reached or ERROR
Health->>Notif: spawn_popen_kill(pi, 0)
Notif->>Spawn: spawn_server_exec_kill()
Spawn->>Child: SIGTERM (or TerminateProcess on Windows)
alt Child ignores SIGTERM after grace period
Spawn->>Child: SIGKILL escalation
end
Spawn-->>Notif: Child exited
Notif-->>Health: code = 128
Health->>Health: break loop
end
end
Note over Health,Scheduler: NEW: Re-check shutdown on every slice
alt Shutdown in progress
Scheduler->>Health: service_running(SERVICE_HEALTH) = false
Health->>Health: Terminate notification wait early
end
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
Sorry, something went wrong.
…ing in spawn server implementations - Added logging for SIGKILL failures in nofork, libuv, and POSIX implementations to enhance debugging. - Clarified timeout behavior to prevent applying caller-defined grace periods twice. - Updated comments to explain SIGKILL escalation scenarios and terminal process states.
There was a problem hiding this comment.
1 issue found across 3 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
Sorry, something went wrong.
… cleanup and prevent indefinite waits
|
You're iterating quickly on this pull request. To help protect your rate limits, cubic has paused automatic reviews on new pushes for now—when you're ready for another review, comment @cubic-dev-ai review. |
Sorry, something went wrong.
|
@cubic-dev-ai please review again |
Sorry, something went wrong.
@stelfrag I have started the AI code review. It will take a few minutes to complete. |
Sorry, something went wrong.
There was a problem hiding this comment.
1 issue found across 1 file (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
Sorry, something went wrong.
|
Sorry, something went wrong.
There was a problem hiding this comment.
When using a fake script, I still had alerts raised. LGTM!
Sorry, something went wrong.
* Add `spawn_server_exec_timedwait` to prevent hanging child processes with configurable timeouts - Introduced `spawn_server_exec_timedwait` across spawn server implementations (POSIX, libuv, nofork, Windows). - Added timeout-based process cleanup for `POPEN_INSTANCE` via `spawn_popen_timedwait`. - Configurable notification execution timeout (`notification_execution_timeout_seconds`) added to health configuration. - Updated alert notification handling to kill hanging processes after exceeding the timeout. - Extended unit tests to validate timed-wait behavior for processes. * Add process timeout clamping and SIGKILL escalation to prevent hanging processes - Clamp negative/zero timeouts to positive defaults to avoid infinite waits. - Escalate hanging child processes from SIGTERM to SIGKILL after timeout expiration. - Ensure consistent behavior across spawn server implementations (POSIX, libuv, nofork, Windows). - Refactor health notification timeout handling to avoid indefinite blocking by slow/hanging processes. * Clarify timeout handling for child process waits and normalize negative timeout behavior - Updated comments to explain bounded timeout behavior (non-infinite waits) for child process management. - Normalized negative timeout values to effectively enable non-blocking polls. - Improved documentation on health notification timeout clamping. * Close child pipes in `spawn_server_exec_timedwait` to prevent hanging processes blocked on I/O. * Clarify timeout handling and escalation logic for child process management - Updated comments to explain PID reuse prevention and bounded timeout behavior. - Enhanced documentation for timeout clamping and child process escalation (SIGKILL after SIGTERM). - Improved error handling for Windows process waits (reporting failed handles as running instead of exited). * Improve error handling in spawn server and popen implementations - Handle status socket errors during `spawn_server_exec_wait` to avoid premature child cleanup and escalate to kill if needed. - Fix null pointer dereference issues in `spawn_popen_timedwait` by adding safety checks before assigning codes. * Resolve wait handling for terminal errors in `spawn_server_exec_timedwait` - Updated logic to treat status socket and process handle errors as terminal instead of transient "still running" states. - Prevent infinite spinning on broken channels or unusable handles during timed waits. - Improved logging for error resolution paths on both POSIX and Windows platforms. * Handle terminal errors in process wait and prevent infinite loops - Updated `SPAWN_TIMEDWAIT_ERROR` handling to distinguish terminal errors from transient "still running" states. - Prevent looping on broken channels or handles to avoid infinite spins. - Refactored escalation logic for SIGKILL if process wait cannot be completed. * Make `status` parameter optional in `spawn_server_exec_timedwait` across all implementations - Add null checks for `status` before assignment to enhance flexibility and prevent potential null pointer dereference. - Update logic in POSIX, libuv, nofork, and Windows implementations. - Improve documentation to clarify `status` as an optional parameter. * Normalize timeout handling and enhance SIGKILL escalation logic across spawn server implementations - Added `SPAWN_KILL_DEFAULT_GRACE_MS` for consistent default grace periods on negative/zero timeouts. - Updated timeout calculations to ensure bounded termination waits before escalating from SIGTERM to SIGKILL. - Refactored logic in POSIX, libuv, and nofork implementations for clarity and consistency. - Improved error handling and cleanup in `spawn_popen_timedwait` to address terminal error scenarios. * Improve error handling for SIGKILL failures and clarify timeout handling in spawn server implementations - Added logging for SIGKILL failures in nofork, libuv, and POSIX implementations to enhance debugging. - Clarified timeout behavior to prevent applying caller-defined grace periods twice. - Updated comments to explain SIGKILL escalation scenarios and terminal process states. * Refactor SIGTERM-to-SIGKILL escalation logic to improve child process cleanup and prevent indefinite waits (cherry picked from commit 4381b68)
| Back | FazBrowse Home | New Git URL |
Summary
Summary by cubic
Bounds alert notification execution with a configurable timeout so hung notifications can’t stall health checks or shutdown. Adds bounded timed waits with SIGTERM→SIGKILL escalation, a sane default grace, and consistent cross‑platform behavior.
New Features
Bug Fixes
Written for commit 1b2f985. Summary will update on new commits.