fix(context): stop() releases the singletons it destroyed (release 26.09.03) - #163
Merged
Conversation
stop() called @pre_destroy on every resolved bean and then left each instance on its registration, so the container went on holding objects whose pools were closed, whose consumers were stopped and whose files were flushed. Two consequences, both silent: get_bean() after a stop returned a DESTROYED singleton rather than failing or rebuilding, and a later start() created a fresh set beside the stale one, so anything walking the registrations — health reporting, metrics, a bean inventory — saw every singleton twice, one live and one dead. stop() now clears the instance from every registration it destroyed, which is what makes it the inverse of start() rather than half of it. It releases only what the container BUILT: anything handed to it as a ready-made object — the container's own self-registration, the context's, anything an embedder registered as an instance — has no factory to rebuild it, so it is left alone and the next start() still works. start() records that distinction as it begins. Found with the same service that surfaced the double-start in 26.09.02: a start/stop/start cycle across two test modules left two EventPublisher instances in one container, one of them dead. Release 26.09.03.
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.
The companion to #162.
stop()called@pre_destroyon every resolved bean and then left eachinstance on its registration, so the container went on holding objects whose pools were closed, whose
consumers were stopped and whose files were flushed.
Two consequences, both silent:
get_bean()after a stop returns a destroyed singleton rather than failing or rebuilding.start()creates a fresh set beside the stale one, so anything walking the registrations— health reporting, metrics, a bean inventory — sees every singleton twice, one live and one dead.
stop()now clears the instance from every registration it destroyed, which is what makes it theinverse of
start()rather than half of it.It releases only what the container built
Anything handed to the container as a ready-made object — its own self-registration, the context's,
anything an embedder registered as an instance — has no factory to rebuild it, so discarding it
would break the next
start().start()now records which instances predate its bean pipeline, andstop()leaves exactly those alone. That distinction is what the first attempt at this fix got wrong:clearing everything made a restart fail with
NameError: name 'Container' is not defined.Found with the same service that surfaced the double-start in #162: a start/stop/start cycle across
two test modules left two
EventPublisherinstances in one container, one of them dead.Verification
pytest tests/(CI's ignore set)mypy src/pyfly --strictruff check/ruff format --check