Resubscribe dependents when a dependency controller is replaced#11
Merged
Conversation
The %{target: _, subscription_ref: _} clause could never match: the
function is only called with single-kind binding states, which carry
:child_target rather than :target.
put_collection_binding_subscription fell back to a bare map without :kind/:source/:filter, and that shape is what actually got persisted for every non-empty collection binding. Those states fell through cleanup_binding_state's silent catch-all, so collection subscriptions were never explicitly unsubscribed when a dependent stopped — process monitors happened to mask it. Use default_collection_binding_state as the fallback and drop the catch-all so shape drift fails loudly.
Binding state only recorded the source controller's name, so after a params change replaced a controller, reconcile considered dependents' bindings live even though their subscriptions died with the old process. Updates from the new instance stopped flowing entirely. Track the pid each subscription was made in and treat a binding as live only when that pid still runs the source. Applies to singleton dependencies and to collection items replaced under the same id.
A stale binding's subscription died with its process, so resolving the source name to the current pid just hands the replacement process a ref it has never seen — a wasted synchronous call during replacement reconciliation. Thread the stored pid through and only unsubscribe when it still matches the running process.
Its only caller reaches it through the validate_or_normalize_dependencies clause that requires dependency_bindings != [], so the empty-list clause can never match — the type checker now proves and reports this. The is_list/1 clause already handles [] identically.
Controllers declared with events: [] compiled the lookup down to
Map.fetch!(%{}, event), which the type checker proves always raises and
reports on every such module — including in downstream applications.
Emit one clause per declared event plus an explicit KeyError fallback,
preserving the previous behavior for undeclared events.
Damirados
reviewed
Jul 7, 2026
Damirados
left a comment
Collaborator
There was a problem hiding this comment.
Remove Co-Autored-By lines from the commits.
8d91324 to
cac6b74
Compare
Damirados
reviewed
Jul 7, 2026
Damirados
left a comment
Collaborator
There was a problem hiding this comment.
Add a proper PR name and description.
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.
No description provided.