Skip to content

Port TopicLeaderDistributionGoal and ExecutionTaskPlanner changes - #10

Open
cnmperalta wants to merge 1 commit into
3.0.4-liftofffrom
kei.cruisecontrol.port-topic-leader-dist
Open

cnmperalta wants to merge 1 commit into
3.0.4-liftofffrom
kei.cruisecontrol.port-topic-leader-dist

Conversation

@cnmperalta

@cnmperalta cnmperalta commented Sep 16, 2026

Copy link
Copy Markdown

Related to INF-9062.

Port Liftoff changes made to (2.4.20-liftoff4), originally written by Andrey. This includes:

Some changes in the 3.0.4 version:

  • Replace leadersOfTopicInBroker and numLeadersOfTopicInBroker with leadersFor and the new built-in numLeadersFor, which both leverage the replicasOfTopicInBroker, which already handles the null case for _topicReplicas.get(topic).
  • ClusterModel.numTopicLeaders(topic) now directly calls broker.numLeadersFor(topic) for each broker in the cluster instead of going through racks.
  • Updated ClusterModelStats.numForAvgTopicLeaders to:
    • Take brokers, topics, and aliveBrokers as parameters to avoid re-computing the same in the method.
    • Merge the variance computation into the brokers loop, gated on broker.isAlive(), instead of iterating through aliveBrokers separately.
  • Uses the double primitive instead of Double for BalancingConstraint.topicLeaderBalancePercentage, matching the refactor in the other methods of the class.
  • Made some style changes so that checkstyle passes.
  • Added test changes to ExecutionTaskPlannerTest, to reflect the change we made in ExecutionTaskPlanner.

Deployment:

  • Merge this to 3.0.4-liftoff.
  • Tag the commit with 3.0.4-liftoff1:
    • git tag 3.0.4-liftoff1 3.0.4-liftoff -m 'Port TopicLeaderDistributionGoal and ExecutionTaskPlanner changes to CC 3.0.4'
  • Merge & deploy https://github.com/liftoffio/liftoff/pull/59932

Port Liftoff changes made to 2.4.20-liftoff4, originally written by
Andrey. This includes:
- Replica movement scheduling improvements introduced in #4.
- Addition of the TopicLeaderDistributionGoal (#5, #6, c509c47).

Some changes in the 3.0.4 version:
- Replace leadersOfTopicInBroker and numLeadersOfTopicInBroker with
  leadersFor and the new built-in numLeadersFor, which both leverage
  the replicasOfTopicInBroker, which already handles the null case for
  _topicReplicas.get(topic).
- ClusterModel.numTopicLeaders(topic) now directly calls
  broker.numLeadersFor(topic) for each broker in the cluster instead of
  going through racks.
- Updated ClusterModelStats.numForAvgTopicLeaders to:
  - Take brokers, topics, and aliveBrokers as parameters to avoid
    re-computing the same in the method.
  - Merge the variance computation into the brokers loop, gated on
    broker.isAlive(), instead of iterating through aliveBrokers
    separately.
- Uses the double primitive instead of Double for
  BalancingConstraint.topicLeaderBalancePercentage, matching the
  refactor in the other methods of the class.
- Made some style changes so that checkstyle passes.
- Added test changes to ExecutionTaskPlannerTest, to reflect the change
  we made in ExecutionTaskPlanner.
@cnmperalta
cnmperalta force-pushed the kei.cruisecontrol.port-topic-leader-dist branch from 24ceb2b to 1a8e077 Compare September 16, 2026 23:31

@cnmperalta cnmperalta left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I marked the areas with code changes I made. The comments are similar to what's in the PR description, just written nearer to the code.

Comment on lines +207 to +215
/**
* Get leader replicas for topic.
* @param topic Topic of the requested replicas.
* @return Leader replicas in this broker sharing the given topic.
*/
public Collection<Replica> leadersFor(String topic) {
return replicasOfTopicInBroker(topic).stream().filter(Replica::isLeader).collect(Collectors.toList());
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I replaced leadersOfTopicInBroker and numLeadersOfTopicInBroker with leadersFor and just used the new built-in numLeadersFor, which both leverage the replicasOfTopicInBroker, which already handles the null case for _topicReplicas.get(topic).

Comment on lines +679 to +685
public int numTopicLeaders(String topic) {
int numTopicLeaders = 0;
for (Broker broker : brokers()) {
numTopicLeaders += broker.numLeadersFor(topic);
}
return numTopicLeaders;
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

ClusterModel.numTopicLeaders(topic) now directly calls broker.numLeadersFor(topic) for each broker in the cluster instead of going through racks.

Comment on lines +496 to +499
private void numForAvgTopicLeaders(ClusterModel clusterModel,
SortedSet<Broker> brokers,
Set<String> topics,
Set<Broker> aliveBrokers) {

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Updated ClusterModelStats.numForAvgTopicLeaders to:

  • Take brokers, topics, and aliveBrokers as parameters to avoid re-computing the same in the method.
  • Merge the variance computation into the brokers loop, gated on broker.isAlive(), instead of iterating through aliveBrokers separately.

/**
* @return Topic leader replica balance percentage for {@link com.linkedin.kafka.cruisecontrol.analyzer.goals.TopicLeaderDistributionGoal}.
*/
public double topicLeaderBalancePercentage() {

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Uses the double primitive instead of Double for BalancingConstraint.topicLeaderBalancePercentage, matching the refactor in the other methods of the class.

assertEquals("First task", _partitionMovement0, partitionMovementTasks.get(0).proposal());
assertEquals("Second task", _partitionMovement2, partitionMovementTasks.get(1).proposal());
assertEquals("Third task", _partitionMovement3, partitionMovementTasks.get(2).proposal());
assertEquals("Second task", _partitionMovement3, partitionMovementTasks.get(1).proposal());

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Added these test changes to ExecutionTaskPlannerTest, to reflect the change we made in ExecutionTaskPlanner.

@PleasingFungus

Copy link
Copy Markdown

Congrats on lucky PR number 10! 💯

@PleasingFungus

Copy link
Copy Markdown

(Did you mean to mark this as a draft PR?)

@cnmperalta
cnmperalta marked this pull request as ready for review September 16, 2026 23:43
@cnmperalta

Copy link
Copy Markdown
Author

(Did you mean to mark this as a draft PR?)

I forgot to mark it as ready for review after I marked it all up. I've done so now haha.

@PleasingFungus

Copy link
Copy Markdown

I'm going to be occupied with OCI work for a bit. @andrey-klochkov-liftoff, I don't suppose you have bandwidth to look at this?

@andrey-klochkov-liftoff

Copy link
Copy Markdown

@andrey-klochkov-liftoff, I don't suppose you have bandwidth to look at this?

No, sorry, I have enough work, and it's been many years since I saw this code so it'd be an expensive context switch.

@PleasingFungus

Copy link
Copy Markdown

Got it. I probably won't be available for this review for a few weeks, unfortunately; up to you if you want to look for another reviewer.

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.

3 participants