Skip to content

fix(context): a restart reproduces a cold start (release 26.09.04) - #164

Merged
ancongui merged 1 commit into
mainfrom
fix/restart-reproduces-cold-start
Sep 10, 2026
Merged

fix(context): a restart reproduces a cold start (release 26.09.04)#164
ancongui merged 1 commit into
mainfrom
fix/restart-reproduces-cold-start

Conversation

@ancongui

Copy link
Copy Markdown
Contributor

Completes the lifecycle trilogy of #162 and #163.

26.09.03 made stop() release the singletons it built, but the registrations the previous start() created were left in place, so the next start() layered a second pipeline on top of them instead of rebuilding.

Two things went wrong, both silent:

  • a @bean reachable under several keys — its concrete class and the protocol it satisfies — stopped being one object. The first start aliased those keys to a single instance; the restart resolved each key independently and called the factory once per key, so get_bean(Protocol) and get_bean(Concrete) returned different singletons.
  • the registration set drifted, because the @conditional_on_* passes re-evaluated against a registry that already held the previous run's output rather than against the user's own definitions.

start() now records exactly which registrations its pipeline added and drops them at the next start, so the registry a restart begins from is the one a cold start begins from.

Two tests pin it: a bean published under an interface stays one instance across a restart, and the registration set after a restart is identical to the set after the cold start.

Gate Result
pytest tests/ 5003 passed, 7 skipped, 0 failed
mypy src/pyfly --strict no issues in 694 source files
ruff check / format --check passed

26.09.03 made stop() release the singletons it built, but the REGISTRATIONS the
previous start() created were left in place, so the next start() layered a second
pipeline on top of them instead of rebuilding.

Two things went wrong, both silent:

- a @bean reachable under several keys — its concrete class and the protocol it
  satisfies — stopped being one object. The first start aliased those keys to a
  single instance; the restart resolved each key independently and called the
  factory once per key, so get_bean(Protocol) and get_bean(Concrete) returned
  different singletons.
- the registration set drifted, because the @conditional_on_* passes re-evaluated
  against a registry that already held the previous run's output rather than
  against the user's own definitions.

start() now records exactly which registrations its pipeline added and drops them
at the next start, so the registry a restart begins from is the one a cold start
begins from.

Completes the lifecycle trilogy of 26.09.02 (idempotent start), 26.09.03 (stop
releases what it destroyed) and this release, all found by one service sharing a
module-level application across test modules.

Release 26.09.04.
@ancongui
ancongui merged commit 84e6251 into main Sep 10, 2026
6 checks passed
@ancongui
ancongui deleted the fix/restart-reproduces-cold-start branch September 10, 2026 04:18
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