Skip to content

feat(decdn_node): enable the systemd watchdog on the node unit - #78

Merged
alpergundogdu merged 2 commits into
mainfrom
feat/decdn-node-systemd-watchdog
Sep 24, 2026
Merged

alpergundogdu merged 2 commits into
mainfrom
feat/decdn-node-systemd-watchdog

Conversation

@alpergundogdu

@alpergundogdu alpergundogdu commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Problem

When every tokio worker in decdn-node is held by work that never yields, the node serves nothing, logs nothing and answers no /metrics scrape. The process keeps running, though, so the unit stays active with Restart=always never firing.

Fix

decdn/decdn#2145 makes the node send WATCHDOG=1 from a task on its runtime when the unit sets WatchdogSec=. This PR turns that on in the role:

  • WatchdogSec={{ decdn_node_watchdog_sec }} and NotifyAccess=main, rendered when decdn_node_watchdog_sec > 0. systemd kills a node that misses the deadline with SIGABRT, and Restart=always brings it back.
  • AF_UNIX is added to RestrictAddressFamilies, because the heartbeat goes over NOTIFY_SOCKET.
  • decdn_node_watchdog_sec defaults to 0, which omits all three directives. The role cannot tell whether the binary it installs sends the heartbeat, so the watchdog is opt-in. Set it (e.g. 60) once the deployed build includes feat(node): heartbeat the systemd watchdog from the runtime and test serve-loop starvation decdn#2145.

Enabling it: set decdn_node_watchdog_sec only for hosts whose decdn-node build includes decdn/decdn#2145. An older binary sends no heartbeat, so systemd would kill it every period.

I checked the rendered unit with trim_blocks=True (Ansible's default) for both 60 and 0.

🤖 Generated with Claude Code

decdn-node heartbeats WATCHDOG=1 from its tokio runtime when the unit sets
WatchdogSec (decdn/decdn#2145). A node whose runtime workers are all held
by work that never yields stops the heartbeat, and systemd restarts it
instead of leaving it `active` while it serves nothing.

- WatchdogSec={{ decdn_node_watchdog_sec }} (default 60) plus
  NotifyAccess=main, so systemd accepts the main PID's heartbeat.
- AF_UNIX joins RestrictAddressFamilies, since the heartbeat goes over
  NOTIFY_SOCKET.
- decdn_node_watchdog_sec: 0 omits all three, for a binary that predates
  the heartbeat and would otherwise be killed every period.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings September 24, 2026 10:36

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

The new watchdog is enabled by default (60s) despite being incompatible with older decdn-node binaries, which can cause immediate restart loops unless users proactively override it.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 Medium severity

Open (1)
What changed in this PR

This PR enables systemd watchdog support for the decdn-node systemd unit rendered by the decdn_node Ansible role, so systemd can restart the node when it becomes runtime-stalled (e.g., tokio workers stop yielding) but the process remains alive.

Changes:

  • Add conditional WatchdogSec= + NotifyAccess=main to the node unit when decdn_node_watchdog_sec > 0.
  • Extend RestrictAddressFamilies= to conditionally allow AF_UNIX when watchdog is enabled (for NOTIFY_SOCKET).
  • Introduce decdn_node_watchdog_sec role default (currently set to 60) with documentation about disabling it for older binaries.
File Description
ansible/​roles/​decdn_node/​templates/​decdn-node.service.j2 Conditionally enables systemd watchdog directives and allows AF_UNIX only when needed.
ansible/​roles/​decdn_node/​defaults/​main.yml Adds a new default variable controlling watchdog behavior and documents the version dependency.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread ansible/roles/decdn_node/defaults/main.yml Outdated
The role cannot tell whether the binary it installs heartbeats, and a
binary that does not is killed every period, so decdn_node_watchdog_sec
defaults to 0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@alpergundogdu
alpergundogdu merged commit 3979544 into main Sep 24, 2026
16 checks passed
@alpergundogdu
alpergundogdu deleted the feat/decdn-node-systemd-watchdog branch September 24, 2026 11:00
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