-
Notifications
You must be signed in to change notification settings - Fork 4k
grpclb: pick_first delegation #12568
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
kannanjgithub
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review comments.
| inOrder.verify(helper).updateBalancingState(eq(READY), pickerCaptor.capture()); | ||
| RoundRobinPicker picker3 = (RoundRobinPicker) pickerCaptor.getValue(); | ||
| assertThat(picker3.dropList).containsExactly(null, null); | ||
| assertThat(picker3.pickList).containsExactly( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly here, don't remove the assertion for the pickList with the fake subchannel, assert using accessor in ChildLbPickerEntry for use by the test.
| // TRANSIENT_FAILURE | ||
| Status error = Status.UNAVAILABLE.withDescription("Simulated connection error"); | ||
| deliverSubchannelState(subchannel, ConnectivityStateInfo.forTransientFailure(error)); | ||
| inOrder.verify(helper).updateBalancingState(eq(TRANSIENT_FAILURE), pickerCaptor.capture()); | ||
| RoundRobinPicker picker2 = (RoundRobinPicker) pickerCaptor.getValue(); | ||
| assertThat(picker2.dropList).containsExactly(null, null); | ||
| assertThat(picker2.pickList).containsExactly(new ErrorEntry(error)); | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not remove the testing for simulated transient failure.
Now we cannot directly do
assertThat(picker2.pickList).containsExactly(new ErrorEntry(error));
as the ErorrEntry is wrapped in a ChildLbPickerEntry. Create accessor for the wrapped entry for use in the unit test so we can assert using that.
| assertThat(mockSubchannels).isEmpty(); | ||
| verify(subchannel).updateAddresses( | ||
| eq(Arrays.asList( | ||
| new EquivalentAddressGroup(backends1.get(0).addr, eagAttrsWithToken("token0001")), | ||
| new EquivalentAddressGroup(backends1.get(1).addr, | ||
| eagAttrsWithToken("token0002"))))); | ||
| inOrder.verify(helper).updateBalancingState(eq(READY), pickerCaptor.capture()); | ||
| RoundRobinPicker picker2 = (RoundRobinPicker) pickerCaptor.getValue(); | ||
| assertThat(picker2.dropList).containsExactly(null, null); | ||
| assertThat(picker2.pickList).containsExactly( | ||
| new BackendEntry(subchannel, new TokenAttachingTracerFactory(getLoadRecorder()))); | ||
| // the same child LB is updated with new addresses. We expect | ||
| // only one subchannel to be created for the whole test. The child LB will call | ||
| // updateAddresses() internally, so we remove the verifications for recreation. | ||
| verify(helper, times(1)).createSubchannel(any(CreateSubchannelArgs.class)); | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PF behavior may be done by a different code now but the behavior should still be the same. Why remove the test for it?
kannanjgithub
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some deleted code still needs to be restored.
| verify(subchannel).requestConnection(); | ||
| assertThat(picker0.dropList).containsExactly(null, null); | ||
| assertThat(picker0.pickList).hasSize(1); | ||
| assertThat(picker0.pickList.get(0)).isInstanceOf(ChildLbPickerEntry.class); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that you have added an accessor in ChildLbPickerEntry we can retrieve that subchannel and do the assertion for it (like you already do below).
| readyEntry.getChildPicker().pickSubchannel(mock(PickSubchannelArgs.class)); | ||
| assertThat(readyResult.getSubchannel()).isEqualTo(subchannel); | ||
|
|
||
| // TRANSIENT_FAILURE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Add back the comment.
| } | ||
|
|
||
| @Test | ||
| public void grpclbWorking_pickFirstMode_lbSendsEmptyAddress() throws Exception { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The removed test code from this test needs to be restored as well.
|
|
||
| // Only one subchannel is created | ||
| // Child pick_first eagerly connects | ||
| verify(helper, atLeast(1)).updateBalancingState(eq(CONNECTING), any()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
capture the picker and do assertions.
| assertThat(picker0.dropList).containsExactly(null, null); | ||
| assertThat(picker0.pickList).containsExactly(new IdleSubchannelEntry(subchannel, syncContext)); | ||
|
|
||
| // PICK_FIRST doesn't eagerly connect | ||
| verify(subchannel, never()).requestConnection(); | ||
|
|
||
| // CONNECTING | ||
| deliverSubchannelState(subchannel, ConnectivityStateInfo.forNonError(CONNECTING)); | ||
| inOrder.verify(helper).updateBalancingState(eq(CONNECTING), pickerCaptor.capture()); | ||
| RoundRobinPicker picker1 = (RoundRobinPicker) pickerCaptor.getValue(); | ||
| assertThat(picker1.dropList).containsExactly(null, null); | ||
| assertThat(picker1.pickList).containsExactly(BUFFER_ENTRY); | ||
|
|
||
| // TRANSIENT_FAILURE | ||
| Status error = Status.UNAVAILABLE.withDescription("Simulated connection error"); | ||
| deliverSubchannelState(subchannel, ConnectivityStateInfo.forTransientFailure(error)); | ||
| inOrder.verify(helper).updateBalancingState(eq(TRANSIENT_FAILURE), pickerCaptor.capture()); | ||
| RoundRobinPicker picker2 = (RoundRobinPicker) pickerCaptor.getValue(); | ||
| assertThat(picker2.dropList).containsExactly(null, null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These deleted lines need to be restored as well similar to the previous test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same for other deleted code below.
|
|
||
| // new addresses will be updated to the existing subchannel | ||
| inOrder.verify(helper, times(1)).createSubchannel(any(CreateSubchannelArgs.class)); | ||
| inOrder.verify(helper).updateBalancingState(eq(IDLE), pickerCaptor.capture()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Restore this statement with the CONNECTING state.
Summary of Changes
This pull request refactors the grpclb load balancer's PICK_FIRST mode to delegate its logic to a standard pick_first load balancing policy.
The key changes are as follows:
grpclb/build.gradleAdded dependency on
grpc-utilmodule to accessForwardingLoadBalancerHelpergrpclb/src/main/java/io/grpc/grpclb/GrpclbState.javaLoadBalancer, LoadBalancerProvider, LoadBalancerRegistry, ResolvedAddresses, FixedResultPicker, ForwardingLoadBalancerHelper
grpclb/src/test/java/io/grpc/grpclb/GrpclbLoadBalancerTest.java