Skip to content

feat: add readiness notification support for process supervisors #752

@endersonmaia

Description

@endersonmaia

📚 Context

When running individual cartesi-rollups-* services (advancer, claimer, evm-reader, validator, etc.) under process supervisors like runit, s6, s6-rc, or systemd, there is currently no way for a service to signal to its supervisor that it has fully started and is ready to accept work.

Supervisors use readiness notifications to:

  • Correctly order service startup (dependency resolution)
  • Avoid routing traffic to services that haven't finished initializing
  • Accurately report service state (starting vs. ready)

Without this mechanism, supervisors must rely on fragile heuristics (e.g. polling the telemetry /readyz endpoint or waiting a fixed delay), making supervision less reliable and harder to configure.

✔️ Solution

There are two standard protocols for readiness notification, which are independent and can coexist:

Option A — --notify-fd flag (runit, s6, nitro, etc.)

Add a --notify-fd <fd> CLI flag to each cartesi-rollups-* binary. When set, the service writes a newline character (\n) to the given file descriptor as soon as it is ready, then closes it.

This is the standard protocol used by:

  • s6 — via s6-notifywhenup: the notification-fd file in the service directory tells s6 which fd to open before execing the service.
  • runit — supports the same fd-based notification via a ./notification-fd file.
  • nitro — supports the same notification protocol.

Example s6 service directory layout:

/etc/s6/cartesi-rollups-advancer/
  run              # exec cartesi-rollups-advancer --notify-fd 3 ...
  notification-fd  # contains: 3

Option B — NOTIFY_SOCKET env var (systemd)

When the environment variable NOTIFY_SOCKET is set (as systemd does for Type=notify units), the service sends a READY=1\n datagram to the unix socket at that path, following the sd_notify(3) protocol. No extra flag is needed — detection is automatic from the environment.

This allows the services to be declared as systemd units of type Type=notify:

[Service]
Type=notify
ExecStart=/usr/bin/cartesi-rollups-advancer ...

Both options should trigger notification after the service has completed initialization (database connection established, first poll cycle done), not merely at process start.

📈 Subtasks

  • Add NotifyFd int field to CreateInfo and Service in pkg/service
  • Add --notify-fd flag to each cartesi-rollups-* binary (advancer, claimer, evm-reader, jsonrpc-api, validator, prt)
  • Wire the flag through each service's config and CreateInfo
  • In Serve(), write \n to the notify fd when ready and close it
  • Detect NOTIFY_SOCKET env var in Serve() and send READY=1\n datagram when set
  • Add tests for both notification paths

Metadata

Metadata

Assignees

No one assigned

    Labels

    triageTo be triaged

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions