diff --git a/BaragonAgentService/src/main/java/com/hubspot/baragon/agent/handlebars/PreferSameRackWeightingHelper.java b/BaragonAgentService/src/main/java/com/hubspot/baragon/agent/handlebars/PreferSameRackWeightingHelper.java index 48c87aecb..75f694d32 100644 --- a/BaragonAgentService/src/main/java/com/hubspot/baragon/agent/handlebars/PreferSameRackWeightingHelper.java +++ b/BaragonAgentService/src/main/java/com/hubspot/baragon/agent/handlebars/PreferSameRackWeightingHelper.java @@ -53,7 +53,8 @@ public CharSequence preferSameRackWeighting(Collection upstreams, } final BigDecimal totalPendingLoad = rackHelper.getTotalPendingLoad(allRacks); final BigDecimal capacity = rackHelper.calculateCapacity(allRacks); - return preferSameRackWeightingOperation(upstreams, currentUpstream, allRacks, capacity, totalPendingLoad, null); + final BigDecimal multiplier = rackHelper.calculateMultiplier(allRacks); + return preferSameRackWeightingOperation(upstreams, currentUpstream, allRacks, capacity, multiplier, totalPendingLoad, null); } /** @@ -70,6 +71,7 @@ public CharSequence preferSameRackWeightingOperation(Collection up UpstreamInfo currentUpstream, List allRacks, BigDecimal capacity, + BigDecimal multiplier, BigDecimal totalPendingLoad, Options options) { @@ -79,8 +81,6 @@ public CharSequence preferSameRackWeightingOperation(Collection up final String currentRack = agentMetadata.getEc2().getAvailabilityZone().get(); final String testingRack = currentUpstream.getRackId().get(); - - final BigDecimal countOfAllRacks = new BigDecimal(allRacks.size()); final BigDecimal countOfCurrentRack = new BigDecimal(Collections.frequency(allRacks, currentRack)); final BigDecimal countOfTestingRack = new BigDecimal((Collections.frequency(allRacks, testingRack))); // assume this is always in upstream @@ -94,7 +94,7 @@ public CharSequence preferSameRackWeightingOperation(Collection up if (load.compareTo(capacity) == -1) { // load is less than capacity return ""; } - final BigDecimal weight = capacity.multiply(countOfAllRacks).multiply(countOfTestingRack); + final BigDecimal weight = capacity.multiply(multiplier); return getWeight(weight); } @@ -110,7 +110,7 @@ public CharSequence preferSameRackWeightingOperation(Collection up } final BigDecimal pendingLoadFromCurrentRackToTestingRack = (extraCapacityInTestingRack.divide(totalPendingLoad, 10, BigDecimal.ROUND_HALF_UP)).multiply(pendingLoadInCurrentRack); - final BigDecimal weight = pendingLoadFromCurrentRackToTestingRack.multiply(countOfAllRacks).multiply(countOfTestingRack); + final BigDecimal weight = pendingLoadFromCurrentRackToTestingRack.multiply(multiplier); return getWeight(weight); } return ""; // If the required data isn't present for some reason, send even traffic everywhere (i.e. everything has a weight of 1) diff --git a/BaragonAgentService/src/main/java/com/hubspot/baragon/agent/handlebars/RackMethodsHelper.java b/BaragonAgentService/src/main/java/com/hubspot/baragon/agent/handlebars/RackMethodsHelper.java index 5fb74675d..04d2e1e22 100644 --- a/BaragonAgentService/src/main/java/com/hubspot/baragon/agent/handlebars/RackMethodsHelper.java +++ b/BaragonAgentService/src/main/java/com/hubspot/baragon/agent/handlebars/RackMethodsHelper.java @@ -33,6 +33,11 @@ public BigDecimal calculateCapacity(List allRacks) { return new BigDecimal((new HashSet<>(allRacks)).size()).divide(new BigDecimal(allRacks.size()), 10, BigDecimal.ROUND_HALF_UP); } + public BigDecimal calculateMultiplier(List allRacks) { + /* multiplier is the factor by which fractional weights should be scaled to get an integer value*/ + return new BigDecimal((new HashSet<>(allRacks)).size()).multiply(new BigDecimal(allRacks.size())); + } + /** * @param allRacks * @return the total pending load that have to be distributed to other upstreams diff --git a/BaragonAgentService/src/test/java/com/hubspot/baragon/agent/PreferSameRackWeightingBalancedTest.java b/BaragonAgentService/src/test/java/com/hubspot/baragon/agent/PreferSameRackWeightingBalancedTest.java index acb733841..93cb47ab3 100644 --- a/BaragonAgentService/src/test/java/com/hubspot/baragon/agent/PreferSameRackWeightingBalancedTest.java +++ b/BaragonAgentService/src/test/java/com/hubspot/baragon/agent/PreferSameRackWeightingBalancedTest.java @@ -61,7 +61,7 @@ public void testSimpleCase1B() { CharSequence result = helper.preferSameRackWeighting(UPSTREAMS, currentUpstream, null); results.add(result.toString()); } - Assert.assertEquals(Arrays.asList("", "", "weight=4", "backup", "backup"), results); + Assert.assertEquals(Arrays.asList("weight=2", "weight=2", "weight=16", "backup", "backup"), results); } @Test @@ -74,7 +74,7 @@ public void testSimpleCase1C() { CharSequence result = helper.preferSameRackWeighting(UPSTREAMS, currentUpstream, null); results.add(result.toString()); } - Assert.assertEquals(Arrays.asList("", "", "backup", "weight=4", "backup"), results); + Assert.assertEquals(Arrays.asList("weight=2", "weight=2", "backup", "weight=16", "backup"), results); } @Test @@ -87,7 +87,7 @@ public void testSimpleCase1E() { CharSequence result = helper.preferSameRackWeighting(UPSTREAMS, currentUpstream, null); results.add(result.toString()); } - Assert.assertEquals(Arrays.asList("", "", "backup", "backup", "weight=4"), results); + Assert.assertEquals(Arrays.asList("weight=2", "weight=2", "backup", "backup", "weight=16"), results); } @Test @@ -104,7 +104,7 @@ public void testSimpleCase1D() { } - private static final Collection LARGER_AVAILABILITY_ZONES = Arrays.asList("us-east-1a", "us-east-1a", "us-east-1b", "us-east-1b", "us-east-1b", "us-east-1b", "us-east-1c", "us-east-1c", "us-east-1c", "us-east-1e", "us-east-1e"); + private static final Collection LARGER_AVAILABILITY_ZONES = Arrays.asList("us-east-1a", "us-east-1a", "us-east-1b", "us-east-1b", "us-east-1b", "us-east-1b", "us-east-1c", "us-east-1c", "us-east-1c", "us-east-1c", "us-east-1e", "us-east-1e"); private static final Collection MANY_UPSTREAMS = LARGER_AVAILABILITY_ZONES.stream().map((availabilityZone) -> new UpstreamInfo("testhost:8080", Optional.absent(), Optional.of(availabilityZone))).collect(Collectors.toList()); @@ -118,7 +118,7 @@ public void testLargerCase1A() { CharSequence result = helper.preferSameRackWeighting(MANY_UPSTREAMS, currentUpstream, null); results.add(result.toString()); } - Assert.assertEquals(Arrays.asList("weight=8", "weight=8", "weight=2", "weight=2", "weight=2", "weight=2", "", "", "", "backup", "backup"), results); + Assert.assertEquals(Arrays.asList("weight=16", "weight=16", "weight=2", "weight=2", "weight=2", "weight=2", "weight=2", "weight=2", "weight=2", "weight=2", "backup", "backup"), results); } @Test @@ -131,7 +131,7 @@ public void testLargerCase1B() { CharSequence result = helper.preferSameRackWeighting(MANY_UPSTREAMS, currentUpstream, null); results.add(result.toString()); } - Assert.assertEquals(Arrays.asList("backup", "backup", "", "", "", "", "backup", "backup", "backup", "backup", "backup"), results); + Assert.assertEquals(Arrays.asList("backup", "backup", "", "", "", "", "backup", "backup", "backup", "backup", "backup", "backup"), results); } @Test @@ -144,7 +144,7 @@ public void testLargerCase1C() { CharSequence result = helper.preferSameRackWeighting(MANY_UPSTREAMS, currentUpstream, null); results.add(result.toString()); } - Assert.assertEquals(Arrays.asList("backup", "backup", "backup", "backup", "backup", "backup", "", "", "", "backup", "backup"), results); + Assert.assertEquals(Arrays.asList("backup", "backup", "backup", "backup", "backup", "backup", "", "", "", "", "backup", "backup"), results); } @Test @@ -157,7 +157,7 @@ public void testLargerCase1D() { CharSequence result = helper.preferSameRackWeighting(MANY_UPSTREAMS, currentUpstream, null); results.add(result.toString()); } - Assert.assertEquals(Arrays.asList("", "", "", "", "", "", "", "", "", "", ""), results); + Assert.assertEquals(Arrays.asList("", "", "", "", "", "", "", "", "", "", "", ""), results); } @Test @@ -170,7 +170,7 @@ public void testLargerCase1E() { CharSequence result = helper.preferSameRackWeighting(MANY_UPSTREAMS, currentUpstream, null); results.add(result.toString()); } - Assert.assertEquals(Arrays.asList("backup", "backup", "weight=2", "weight=2", "weight=2", "weight=2", "", "", "", "weight=8", "weight=8"), results); + Assert.assertEquals(Arrays.asList("backup", "backup", "weight=2", "weight=2", "weight=2", "weight=2", "weight=2", "weight=2", "weight=2", "weight=2", "weight=16", "weight=16"), results); } private static final Collection NULL_AVAILABILITY_ZONES = Arrays.asList(null, null, null, null); @@ -202,7 +202,7 @@ public void testBigDecimalToIntegerCase1B() { CharSequence result = helper.preferSameRackWeighting(NEW_UPSTREAMS, currentUpstream, null); results.add(result.toString()); } - Assert.assertEquals(Arrays.asList("weight=6", "weight=6", "", "", "", "", "", ""), results); + Assert.assertEquals(Arrays.asList("weight=9", "weight=9", "", "", "", "", "", ""), results); } @Test public void testBigDecimalToIntegerCase1E() {