grpc-js: Fix connectivity state change event sequencing #2421
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 test in #2419 revealed a couple of bugs related to the order of connectivity state change events:
PickFirstLoadBalancer#pickSubchannel
informs its parent of the state change before resolving its own internal state, and as a result arbitrary code can run at that point.Subchannel#transitionToState
can eventually result in API calls that cause additional state changes, causing potential reentrancy intransitionToState
which can result in out-of-order state change notifications.The changes to fix this are:
PickFirstLoadBalancer#pickSubchannel
to the end.listener
list inSubchannel
to a set to simplify interacting with it and to allow removing listeners during the iteration.transitionToState
are asynchronous with respect to surface API calls, to avoid reentranttransitionToState
calls.I adapted the test from #2419 to test this combination of bugs.