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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions