feat(api): reserve HealthStatus enum + health field on ContainerSnapshot#1504
Draft
chrisgeo wants to merge 1 commit intoapple:mainfrom
Draft
feat(api): reserve HealthStatus enum + health field on ContainerSnapshot#1504chrisgeo wants to merge 1 commit intoapple:mainfrom
chrisgeo wants to merge 1 commit intoapple:mainfrom
Conversation
Adds a new public enum HealthStatus { none, starting, healthy, unhealthy }
and a new optional 'health: HealthStatus?' field on ContainerSnapshot,
defaulting to nil at all construction sites.
Motivation
----------
External orchestrators that drive the API server (the canonical use
case is the compose-spec depends_on: condition: service_healthy gate)
need to know whether a container is up AND healthy, not just up. Today
ContainerSnapshot exposes .running for any started container, so
consumers have to fall back to .running and treat liveness == health.
Real workloads (databases that take seconds to accept connections,
queue brokers that warm up an in-memory state) hit this regularly and
end up either waiting too long or proceeding too early.
Scope of this PR (deliberately minimal)
---------------------------------------
This PR is data-shape only. It adds the enum and the field to the SDK.
It does NOT wire a healthcheck observer into the daemon: at runtime
the field is always nil, so the on-the-wire behavior is unchanged
modulo one new Codable key on ContainerSnapshot.
Why ship a nil-only field?
~~~~~~~~~~~~~~~~~~~~~~~~~~
A container-level healthcheck observer is a non-trivial design
discussion (where does the spec live? does the API server exec into
the container, or does the runtime drive it? does it leak into the
sandbox boundary?) and we'd rather have that discussion separately,
referencing a concrete companion issue. Reserving the SDK shape now
lets downstream tools start coding against the field with the
'always nil today' guarantee documented inline; flipping the
implementation on later does not require another SDK-shape PR.
Wire compatibility
------------------
ContainerSnapshot is marshaled as Codable JSON over XPC. Adding an
optional field is forward-compatible:
- Older clients reading from a newer server: ignore the new key.
- Newer clients reading from an older server: decode health as nil.
Files
-----
- Sources/ContainerResource/Container/HealthStatus.swift (new):
the enum, with cases documented and a note on the daemon-side
observer caveat.
- Sources/ContainerResource/Container/ContainerSnapshot.swift:
new optional field + init parameter (default nil).
Companion issue
---------------
Filed at apple/container with the design proposal for the eventual
healthcheck observer; this PR is deliberately the smaller surface so
the data shape can land independently of that discussion.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Companion issue: #1502
Type of Change
Motivation and Context
External orchestrators that drive the API server (the canonical use case is a Compose-spec orchestrator implementing
depends_on: condition: service_healthy) need to know whether a container is up AND healthy, not just up. TodayContainerSnapshotexposes.runningfor any started container, so consumers fall back to treating liveness as health. Real workloads (databases that take seconds to accept connections, queue brokers warming up in-memory state) hit this regularly.This PR is data-shape only: it adds a public
HealthStatusenum + an optionalhealth: HealthStatus?field onContainerSnapshot. It does NOT wire a healthcheck observer into the daemon — at runtime the field is alwaysnil. The on-the-wire behavior is unchanged modulo one newCodablekey onContainerSnapshot.See #1502 for the full motivation, the rationale for shipping a
nil-only field today, and the open design questions for the eventual observer.What this PR changes
Sources/ContainerResource/Container/HealthStatus.swift(new): the enum, with each case documented.Sources/ContainerResource/Container/ContainerSnapshot.swift: new optionalhealth: HealthStatus?field with a defaulted init parameter; existing construction sites compile unchanged. Inline doc on the field flags the "always nil today" caveat so consumers know not to wait on it.Total: 2 files (1 new + 1 modified), +45/-1.
Why ship a
nil-only field?A container-level healthcheck observer is a non-trivial design discussion (where the healthcheck spec lives, who runs probes, sandbox-boundary semantics, cadence/retry/start_period, etc.). We would rather have that discussion separately, against a concrete companion design issue, than couple it to the SDK shape PR.
Reserving the SDK shape now lets downstream tools start coding against the field with the documented
nil-today guarantee inline; flipping the implementation on later does not require another SDK-shape PR.If maintainers prefer the opposite path (block the SDK shape until an observer design lands), we will park this PR and open a design discussion issue instead — please indicate preference on #1502.
Wire compatibility
ContainerSnapshotis marshaled asCodableJSON over XPC. Adding an optional field is forward-compatible:healthasnil.Testing
swift buildclean on macOS 26 / Apple silicon, including downstream targets that consumeContainerSnapshot).nil); a Codable round-trip test for the new optional key is straightforward to add if maintainers want it.Status
Draft. Filed alongside #1502. Marked draft until a maintainer signals direction on the SDK-shape-vs-defer-until-observer decision.