Skip to content

refactor: split cmd/confd run startup orchestration #602

@abtreece

Description

@abtreece

Problem

cmd/confd.run() has accumulated too many responsibilities and is acting as the startup supervisor, configuration resolver, dependency builder, observability initializer, processor selector, signal loop, and shutdown coordinator.

Verified in cmd/confd/cli.go:384-615. The function currently handles:

  • TOML loading and env processing.
  • Timeout/retry propagation into backend config.
  • Logging setup.
  • validation/preflight dispatch.
  • SRV discovery.
  • template cache initialization.
  • backend construction.
  • metrics HTTP server creation and goroutine startup.
  • root context creation.
  • template config construction.
  • watch/interval processor selection.
  • systemd notification setup.
  • signal handling and shutdown.

Why this is a problem

The function is difficult to test in isolation because most behavior is tied together in one long control path. Small changes to startup or shutdown behavior risk affecting unrelated concerns, and adding a new runtime feature makes this function larger.

It also makes ownership unclear: metrics server lifecycle, backend lifecycle, processor lifecycle, systemd lifecycle, and signal handling are all coordinated directly in the CLI command implementation.

Suggested refactor

Split run() into smaller units with explicit inputs/outputs:

  • LoadRuntimeConfig or equivalent for config resolution.
  • BuildBackendConfig / BuildStoreClient.
  • StartObservability for metrics and health endpoints.
  • BuildTemplateConfig.
  • BuildProcessor.
  • RunSupervisor for signal handling, reload, and shutdown.

Keep run() as a thin orchestration layer that wires these pieces together.

Acceptance criteria

  • Startup pieces are testable without running the whole process loop.
  • Metrics/server setup can be tested independently from backend config merging.
  • Signal/shutdown behavior is isolated in a supervisor-style component.
  • run() is short enough to read as orchestration rather than implementation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions