Skip to content

feat(core): add an additive error-return service registration path #3997

Description

@jrschumacher

Release classification

Parent: #3996 — Roadmap to OpenTDF v1.

Proposed class: v1-assurance. Score: 5/10 (correctness/reliability 2/3; compatibility 2/3; operability 1/2; explicit v1 dependency 0/2). No explicit release dependency is assumed. Scores describe release necessity, not implementation value; confirmed security/correctness/compatibility failures override the score.

Roadmap reference: ROAD-S01.

Motivation

A service’s Start method already returns an error, including migration failures, but the public registration callback cannot return one. RegisterFunc currently returns only an implementation and optional HTTP handler, and Service.Start invokes it before setting Started. Runtime constructors therefore have no uniform way to report an ordinary startup failure through the registry. Some built-ins compensate with panic-style behavior; more importantly, extension authors cannot opt into normal error propagation without changing the public seam.

Source: RegisterFunc, ServiceOptions, and Service.Start.

Scoped deliverable

Add an additive error-capable registration callback (name and exact shape to be chosen in review), and teach Service.Start to use it. Preserve the existing RegisterFunc source and behavior. Define and validate the ambiguous cases: neither callback configured, both configured, callback returns a partial implementation/handler with an error, and cleanup ownership after failure. A failed registration must not mark the service started.

This issue does not migrate every built-in service, remove/deprecate the legacy callback, redesign dependency injection, or bundle the first adopter. A representative adopter can follow after the seam is proven.

Acceptance tests

  • An error returned by the new callback is returned by Service.Start and Started remains false.
  • Existing RegisterFunc registrations compile and behave unchanged.
  • Both-callback and neither-callback configurations have an explicit, tested result rather than an accidental nil panic.
  • Tests establish who cleans up resources created before the callback fails; normal registry shutdown must not be assumed to cover a service that never started.
  • Existing migration-error and already-started behavior remains intact.
  • Focused registry tests and existing server service-start tests pass.

Rollout and impact

Actual controls today: none are needed for the legacy path; there is no error-return callback. Service.Start is already an error boundary.
Proposed control: additive opt-in adoption while the old callback remains supported. No runtime feature flag is necessary because unmodified registrations retain their current path. Any future retirement is separate compatibility work.

  • Downstream source changes: no required change for legacy registrations; optional to adopt.
  • Complexity: low, provided callback precedence and cleanup are explicit.
  • Coupling: conditional/high review sensitivity because this is a public extension seam.
  • Dependencies: none; enables later constructor migrations.

v1 rationale

Predictable, testable startup failure handling is a useful v1 enabler, but this seam alone is not a demonstrated release blocker. Owners should gate only if an agreed v1 service or supported extension cannot report required startup failures safely without it.

Related: #2981 covers service-mocking utilities, not this callback contract. Do not make that broader helper package a prerequisite unless the first tests genuinely need it.

Delivery flags

Required downstream adaptation Existing feature gate High complexity High coupling
NO required; optional adopter changes N/A for additive opt-in callback NO within bounded seam CONDITIONAL: public registration callers

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions