Skip to content

docs: design note for AppService start/stop ordering - #35

Merged
rocketraman merged 1 commit into
masterfrom
claude/service-ordering-design
Oct 19, 2026
Merged

rocketraman merged 1 commit into
masterfrom
claude/service-ordering-design

Conversation

@rocketraman

@rocketraman rocketraman commented Oct 17, 2026 •

Copy link
Copy Markdown
Owner

Design note only, nothing implemented: docs/service-ordering.adoc.

It came up while reviewing #34, where the Flyway and Exposed services set their order as offsets from JdbcDataSourceService.PRIORITY. The note compares four approaches: the current priority with named bands, phases (layers), provides/requires capabilities, and a hybrid of the last two.

Recommendation: use a closed set of phases (INFRASTRUCTURE, INITIALIZATION, APPLICATION, SERVING) for the coarse order and to give every service a default position. Inside a phase, services order themselves with typed milestones:

  • after: order after the providers of a milestone, if any exist.
  • requires: the same, but the boot fails if no provider exists.

There is no priority. Services that the phases and milestones leave unordered have no guaranteed order. A TieOrder breaks ties by name (in production) or shuffled with a logged seed (in development and tests, via boot-env) to surface missing milestones. priority() is deprecated for one release and still honoured, then removed. With this, boot-db-exposed runs after DbMilestones.SchemaMigrated without knowing about Flyway or Liquibase, and with no migration tool the constraint is simply met. Bootable computes the start plan once, before any service starts. Missing providers, cycles and constraints that point at a later phase fail the boot with a clear message. Shutdown runs the start plan in reverse. Wiring is the same in vanilla, Kodein and Metro, and existing apps keep their current behaviour during the deprecation release.

Customizable: Phase and Milestone are interfaces, so an enum is all it takes to define your own. The phases, the default phase, and how each service's ordering is read (orderingOf) come from a StartOrder passed to Bootable; DefaultStartOrder is used when none is passed. An app can add a phase of its own, replace the phases (mapping library services' default phases onto its own), or override a library service's ordering from the composition root without subclassing it.

@rocketraman
rocketraman force-pushed the claude/service-ordering-design branch from efd19ea to b5cf694 Compare October 18, 2026 12:56
@rocketraman
rocketraman marked this pull request as ready for review October 19, 2026 22:25
Compares a global priority, phases, and provides/requires capabilities,
and recommends phases with milestones inside a phase, so modules order
against roles rather than each other's classes or numbers.
@claude

claude Bot commented Oct 19, 2026

Copy link
Copy Markdown

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

@rocketraman
rocketraman force-pushed the claude/service-ordering-design branch from 2f02eb4 to 7774046 Compare October 19, 2026 22:26
@rocketraman
rocketraman merged commit 7312bb6 into master Oct 19, 2026
2 checks passed
@rocketraman
rocketraman deleted the claude/service-ordering-design branch October 19, 2026 22:29
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.

1 participant