func (b *BalancedLeaderAssigner) Assign(
	topic string,
	curr []admin.PartitionAssignment,
) ([]admin.PartitionAssignment, error) {
	if err := admin.CheckAssignments(curr); err != nil {
		return nil, err
	}
	if len(curr)%len(b.racks) != 0 {
		return nil,
			fmt.Errorf(
				"Cannot balance leaders because the partition count is not a multiple of the number of racks",
			)
	}
	desired := admin.CopyAssignments(curr)
	count := 0
	for {
		count++
		minRack, maxRack := b.minMaxRacks(desired)
		if minRack == maxRack {
			break
		}
		err := b.replaceLeader(topic, count, desired, maxRack, minRack)
		if err != nil {
			return desired, err
		}
		if count > 1000 {
			return nil, errors.New("Too many loops")
		}
	}
	return desired, nil
}
Assign returns a new partition assignment according to the assigner-specific logic.
package assigners
import (
	"errors"
	"fmt"
	"github.com/segmentio/topicctl/pkg/admin"
	"github.com/segmentio/topicctl/pkg/apply/pickers"
)
type BalancedLeaderAssigner struct {
	brokers        []admin.BrokerInfo
	racks          []string
	brokerRacks    map[int]string
	brokersPerRack map[string][]int
	picker         pickers.Picker
}
var _ Assigner = (*BalancedLeaderAssigner)(nil)
func NewBalancedLeaderAssigner(
	brokers []admin.BrokerInfo,
	picker pickers.Picker,
) *BalancedLeaderAssigner {
	return &BalancedLeaderAssigner{
		brokers:        brokers,
		picker:         picker,
		racks:          admin.DistinctRacks(brokers),
		brokerRacks:    admin.BrokerRacks(brokers),
		brokersPerRack: admin.BrokersPerRack(brokers),
	}
}