Skip to content
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

loadbalancer: add builder for the DefaultLoadBalancer #2749

Merged

Conversation

bryce-anderson
Copy link
Contributor

@bryce-anderson bryce-anderson commented Nov 9, 2023

Motivation:

We have a P2C selector but no easy way to use it.

Modifications:

  • add a package private (for now) builder pattern for the DefaultLoadBalancer
  • refactor the testing so that the DefaultLoadBalancer can use the existing unit tests

/**
* Definition of the selector mechanism used for load balancing.
*/
public interface LoadBalancingPolicy {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 for going forward with this approach, this is more aligned with other use-cases, like configuring different HTTP protocol versions on client/server builder and makes it easier to manage externally via ServiceLoader providers if there is only one LB builder with only one provider.

Not now, but in the future we may need to add a "selector" as a method on LoadBalancingPolicy to let users implement their own selectors. For now, +1 for keeping that detail pkg-private.


import java.time.Duration;

public interface LoadBalancerBuilder<ResolvedAddress, C extends LoadBalancedConnection> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need an interface for a builder, vs a concrete class? Will we need this interface internally? Often times concrete builders may have different ways to configure themselves and may not needs the same options.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, interface is helpful when we add support for ServiceLoader providers

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@idelpivnitskiy, couldn't we do something like the RoundRobinLoadBalancers strategy? We could make it a concrete class, make the constructor private, then funneling all builder(String id)'s through the providers that get first dibs to set defaults.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pushed a commit that seems along the lines of what @Scottmitch is suggesting. I like it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a simplistic approach that we use for cases, when we don't need a ServiceLoader provider, like RedirectConfigBuilder, ProxyConfigBuilder, H1ProtocolConfigBuilder, etc. For major objects, like client/server builder, DnsServiceDiscovererBuilder, LB builder it's extremely useful to have access through providers. Providers require them to be interfaces bcz users need to be able to wrap a builder. Wrapper monitors what users set on the builder explicitly and at the build time can modify or add if users missed something. See simple examples in HttpProvidersTest.

@tkountis
Copy link
Contributor

tkountis commented Nov 16, 2023

+1 for this approach

We discussed offline, just to keep everything in one place:

  1. Unrelated to this PR, but i would love an alternative way of applying the outlier detection features. ie. a form of typed-filters (l4-filter, l7-filter etc). -> the builder becomes agnostic of the individual feature

  2. +1 on @idelpivnitskiy point about having support for a custom selector. We can't support all possible features of a LB out of the box, so it would be nice if users had the ability to modify as needed e.g. adding sticky-sessions.

@bryce-anderson
Copy link
Contributor Author

Thanks for the feedback everyone. This seems like the path we want to take so I'm rounding it out now. It's also going to be pretty big so I'm pulling smaller chunks out as smaller PR's for easier reviewing.

@bryce-anderson bryce-anderson changed the title RFC: Option 2: pass in specialized LB policy configs Add configuration builders for the DefaultLoadBalancer Nov 28, 2023
@bryce-anderson bryce-anderson changed the title Add configuration builders for the DefaultLoadBalancer loadbalancer: add builder for the DefaultLoadBalancer Nov 28, 2023
Comment on lines -46 to -54
@Test
void hostDownDoesntCloseConnectionCloseLB() throws Exception {
hostDownDoesntCloseConnection(false);
}

@Test
void hostDownDoesntCloseConnectionCloseLBGracefully() throws Exception {
hostDownDoesntCloseConnection(true);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests were moved to LingeringLoadBalancerTest.

Comment on lines -30 to -46
@Test
void duplicateEventsAreIgnored() {
assertThat(lb.usedAddresses(), is(empty()));

sendServiceDiscoveryEvents(upEvent("address-1"));
assertThat(lb.usedAddresses(), hasSize(1));
sendServiceDiscoveryEvents(upEvent("address-1"));
assertThat(lb.usedAddresses(), hasSize(1));

sendServiceDiscoveryEvents(downEvent("address-1"));
assertThat(lb.usedAddresses(), hasSize(0));
sendServiceDiscoveryEvents(downEvent("address-1"));
assertThat(lb.usedAddresses(), hasSize(0));
}

@Test
void handleDiscoveryEvents() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests were all moved to EagerLoadBalancerTest so they can be shared.

abstract class EagerLoadBalancerTest extends LoadBalancerTest {

@Test
void duplicateEventsAreIgnored() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests were moved from EagerRoundRobinLoadBalancerTest.java to here.

abstract class LingeringLoadBalancerTest extends LoadBalancerTest {

@Test
void hostDownDoesntCloseConnectionCloseLB() throws Exception {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests were moved from LingeringRoundRobinLoadBalancerTest.java.

@bryce-anderson bryce-anderson marked this pull request as ready for review November 29, 2023 21:24
Copy link
Contributor

@tkountis tkountis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@bryce-anderson bryce-anderson merged commit ad80596 into apple:main Dec 6, 2023
15 checks passed
@bryce-anderson bryce-anderson deleted the bl_anderson/lb_config_option2 branch December 6, 2023 17:56
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.

None yet

4 participants