Repository: aurora Updated Branches: refs/heads/master a4853a43f -> 3cb599e1c
Removing ResourceVector enum in favor of ResourceType Reviewed at https://reviews.apache.org/r/46064/ Project: http://git-wip-us.apache.org/repos/asf/aurora/repo Commit: http://git-wip-us.apache.org/repos/asf/aurora/commit/3cb599e1 Tree: http://git-wip-us.apache.org/repos/asf/aurora/tree/3cb599e1 Diff: http://git-wip-us.apache.org/repos/asf/aurora/diff/3cb599e1 Branch: refs/heads/master Commit: 3cb599e1ce6bfcfe9120f5965e2499778bad459a Parents: a4853a4 Author: Maxim Khutornenko <[email protected]> Authored: Tue Apr 12 11:27:57 2016 -0700 Committer: Maxim Khutornenko <[email protected]> Committed: Tue Apr 12 11:27:57 2016 -0700 ---------------------------------------------------------------------- .../scheduler/filter/SchedulingFilterImpl.java | 74 +++++--------------- .../scheduler/resources/ResourceType.java | 71 ++++++++++++++++--- .../filter/SchedulingFilterImplTest.java | 35 +++++---- 3 files changed, 103 insertions(+), 77 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/aurora/blob/3cb599e1/src/main/java/org/apache/aurora/scheduler/filter/SchedulingFilterImpl.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/filter/SchedulingFilterImpl.java b/src/main/java/org/apache/aurora/scheduler/filter/SchedulingFilterImpl.java index f8c57f9..6b5b12b 100644 --- a/src/main/java/org/apache/aurora/scheduler/filter/SchedulingFilterImpl.java +++ b/src/main/java/org/apache/aurora/scheduler/filter/SchedulingFilterImpl.java @@ -25,13 +25,13 @@ import com.google.common.collect.Ordering; import com.google.inject.Inject; import org.apache.aurora.common.inject.TimedInterceptor.Timed; -import org.apache.aurora.common.quantity.Amount; import org.apache.aurora.common.quantity.Data; import org.apache.aurora.gen.MaintenanceMode; import org.apache.aurora.gen.TaskConstraint; import org.apache.aurora.scheduler.configuration.ConfigurationManager; import org.apache.aurora.scheduler.configuration.executor.ExecutorSettings; import org.apache.aurora.scheduler.resources.ResourceSlot; +import org.apache.aurora.scheduler.resources.ResourceType; import org.apache.aurora.scheduler.storage.entities.IAttribute; import org.apache.aurora.scheduler.storage.entities.IConstraint; import org.apache.aurora.scheduler.storage.entities.IHostAttributes; @@ -41,80 +41,44 @@ import static java.util.Objects.requireNonNull; import static org.apache.aurora.gen.MaintenanceMode.DRAINED; import static org.apache.aurora.gen.MaintenanceMode.DRAINING; import static org.apache.aurora.scheduler.configuration.ConfigurationManager.DEDICATED_ATTRIBUTE; -import static org.apache.aurora.scheduler.filter.SchedulingFilterImpl.ResourceVector.CPU; -import static org.apache.aurora.scheduler.filter.SchedulingFilterImpl.ResourceVector.DISK; -import static org.apache.aurora.scheduler.filter.SchedulingFilterImpl.ResourceVector.PORTS; -import static org.apache.aurora.scheduler.filter.SchedulingFilterImpl.ResourceVector.RAM; +import static org.apache.aurora.scheduler.resources.ResourceType.CPUS; +import static org.apache.aurora.scheduler.resources.ResourceType.DISK_MB; +import static org.apache.aurora.scheduler.resources.ResourceType.PORTS; +import static org.apache.aurora.scheduler.resources.ResourceType.RAM_MB; /** * Implementation of the scheduling filter that ensures resource requirements of tasks are * fulfilled, and that tasks are allowed to run on the given machine. */ public class SchedulingFilterImpl implements SchedulingFilter { - private static final Optional<Veto> NO_VETO = Optional.absent(); - private static final Set<MaintenanceMode> VETO_MODES = EnumSet.of(DRAINING, DRAINED); - // Scaling ranges to use for comparison of vetos. This has no real bearing besides trying to - // determine if a veto along one resource vector is a 'stronger' veto than that of another vector. - // The values below represent the maximum resources on a typical slave machine. @VisibleForTesting - enum ResourceVector { - CPU("CPU", 16), - RAM("RAM", Amount.of(24, Data.GB).as(Data.MB)), - DISK("disk", Amount.of(450, Data.GB).as(Data.MB)), - PORTS("ports", 1000); - - private final String name; - private final int range; - @VisibleForTesting - int getRange() { - return range; - } - - ResourceVector(String name, int range) { - this.name = name; - this.range = range; - } - - Optional<Veto> maybeVeto(double available, double requested) { - double tooLarge = requested - available; - if (tooLarge <= 0) { - return NO_VETO; - } else { - return Optional.of(veto(tooLarge)); - } - } - - private static int scale(double value, int range) { - return Math.min( - VetoType.INSUFFICIENT_RESOURCES.getScore(), - (int) (VetoType.INSUFFICIENT_RESOURCES.getScore() * value) / range); - } - - @VisibleForTesting - Veto veto(double excess) { - return Veto.insufficientResources(name, scale(excess, range)); - } + static int scale(double value, int range) { + return Math.min( + VetoType.INSUFFICIENT_RESOURCES.getScore(), + (int) (VetoType.INSUFFICIENT_RESOURCES.getScore() * value) / range); } private static void maybeAddVeto( ImmutableSet.Builder<Veto> vetoes, - ResourceVector vector, + ResourceType resourceType, double available, double requested) { - Optional<Veto> veto = vector.maybeVeto(available, requested); - if (veto.isPresent()) { - vetoes.add(veto.get()); + double tooLarge = requested - available; + if (tooLarge > 0) { + vetoes.add(Veto.insufficientResources( + resourceType.getAuroraName(), + scale(tooLarge, resourceType.getScalingRange()))); } } private static Set<Veto> getResourceVetoes(ResourceSlot available, ResourceSlot required) { ImmutableSet.Builder<Veto> vetoes = ImmutableSet.builder(); - maybeAddVeto(vetoes, CPU, available.getNumCpus(), required.getNumCpus()); - maybeAddVeto(vetoes, RAM, available.getRam().as(Data.MB), required.getRam().as(Data.MB)); - maybeAddVeto(vetoes, DISK, available.getDisk().as(Data.MB), required.getDisk().as(Data.MB)); + maybeAddVeto(vetoes, CPUS, available.getNumCpus(), required.getNumCpus()); + maybeAddVeto(vetoes, RAM_MB, available.getRam().as(Data.MB), required.getRam().as(Data.MB)); + maybeAddVeto(vetoes, DISK_MB, available.getDisk().as(Data.MB), required.getDisk().as(Data.MB)); maybeAddVeto(vetoes, PORTS, available.getNumPorts(), required.getNumPorts()); return vetoes.build(); } @@ -161,7 +125,7 @@ public class SchedulingFilterImpl implements SchedulingFilter { private Optional<Veto> getMaintenanceVeto(MaintenanceMode mode) { return VETO_MODES.contains(mode) ? Optional.of(Veto.maintenance(mode.toString().toLowerCase())) - : NO_VETO; + : Optional.absent(); } private boolean isDedicated(IHostAttributes attributes) { http://git-wip-us.apache.org/repos/asf/aurora/blob/3cb599e1/src/main/java/org/apache/aurora/scheduler/resources/ResourceType.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/aurora/scheduler/resources/ResourceType.java b/src/main/java/org/apache/aurora/scheduler/resources/ResourceType.java index fc9b10b..b6fc949 100644 --- a/src/main/java/org/apache/aurora/scheduler/resources/ResourceType.java +++ b/src/main/java/org/apache/aurora/scheduler/resources/ResourceType.java @@ -15,40 +15,93 @@ package org.apache.aurora.scheduler.resources; import com.google.common.annotations.VisibleForTesting; +import org.apache.aurora.common.quantity.Amount; +import org.apache.aurora.common.quantity.Data; + import static java.util.Objects.requireNonNull; /** - * Describes Mesos resource types. + * Describes Mesos resource types and their Aurora traits. */ @VisibleForTesting public enum ResourceType { /** * CPU resource. */ - CPUS("cpus"), + CPUS("cpus", "CPU", 16), /** * RAM resource. */ - RAM_MB("mem"), + RAM_MB("mem", "RAM", Amount.of(24, Data.GB).as(Data.MB)), /** * DISK resource. */ - DISK_MB("disk"), + DISK_MB("disk", "disk", Amount.of(450, Data.GB).as(Data.MB)), /** * Port resource. */ - PORTS("ports"); + PORTS("ports", "ports", 1000); + + /** + * Mesos resource name. + */ + private final String mesosName; - private final String resourceName; + /** + * Aurora resource name. + */ + private final String auroraName; - ResourceType(String resourceName) { - this.resourceName = requireNonNull(resourceName); + /** + * Scaling range to use for comparison of scheduling vetoes. This has no real bearing besides + * trying to determine if a veto along one resource vector is a 'stronger' veto than that of + * another vector. The value represents the typical slave machine resources. + */ + private final int scalingRange; + + /** + * Describes a Resource type. + * + * @param mesosName See {@link #getMesosName()} for more details. + * @param auroraName See {@link #getAuroraName()} for more details. + * @param scalingRange See {@link #getScalingRange()} for more details. + */ + ResourceType(String mesosName, String auroraName, int scalingRange) { + this.mesosName = requireNonNull(mesosName); + this.auroraName = requireNonNull(auroraName); + this.scalingRange = scalingRange; } + /** + * Gets Mesos resource name. + * <p> + * @see <a href="https://github.com/apache/mesos/blob/master/include/mesos/mesos.proto/">Mesos + * protobuf for more details</a> + * + * @return Mesos resource name. + */ public String getMesosName() { - return resourceName; + return mesosName; + } + + /** + * Gets resource name for internal Aurora representation (e.g. in the UI). + * + * @return Aurora resource name. + */ + public String getAuroraName() { + return auroraName; + } + + /** + * Returns scaling range for comparing scheduling vetoes. + * + * @return Resource scaling range. + */ + public int getScalingRange() { + return scalingRange; } } http://git-wip-us.apache.org/repos/asf/aurora/blob/3cb599e1/src/test/java/org/apache/aurora/scheduler/filter/SchedulingFilterImplTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/aurora/scheduler/filter/SchedulingFilterImplTest.java b/src/test/java/org/apache/aurora/scheduler/filter/SchedulingFilterImplTest.java index 1d9d5fc..6370a12 100644 --- a/src/test/java/org/apache/aurora/scheduler/filter/SchedulingFilterImplTest.java +++ b/src/test/java/org/apache/aurora/scheduler/filter/SchedulingFilterImplTest.java @@ -41,6 +41,7 @@ import org.apache.aurora.scheduler.filter.SchedulingFilter.VetoType; import org.apache.aurora.scheduler.mesos.Offers; import org.apache.aurora.scheduler.mesos.TaskExecutors; import org.apache.aurora.scheduler.resources.ResourceSlot; +import org.apache.aurora.scheduler.resources.ResourceType; import org.apache.aurora.scheduler.resources.Resources; import org.apache.aurora.scheduler.storage.entities.IAttribute; import org.apache.aurora.scheduler.storage.entities.IHostAttributes; @@ -51,10 +52,10 @@ import org.junit.Test; import static org.apache.aurora.scheduler.configuration.ConfigurationManager.DEDICATED_ATTRIBUTE; import static org.apache.aurora.scheduler.filter.AttributeAggregate.EMPTY; -import static org.apache.aurora.scheduler.filter.SchedulingFilterImpl.ResourceVector.CPU; -import static org.apache.aurora.scheduler.filter.SchedulingFilterImpl.ResourceVector.DISK; -import static org.apache.aurora.scheduler.filter.SchedulingFilterImpl.ResourceVector.PORTS; -import static org.apache.aurora.scheduler.filter.SchedulingFilterImpl.ResourceVector.RAM; +import static org.apache.aurora.scheduler.resources.ResourceType.CPUS; +import static org.apache.aurora.scheduler.resources.ResourceType.DISK_MB; +import static org.apache.aurora.scheduler.resources.ResourceType.PORTS; +import static org.apache.aurora.scheduler.resources.ResourceType.RAM_MB; import static org.junit.Assert.assertEquals; public class SchedulingFilterImplTest extends EasyMockTest { @@ -133,7 +134,7 @@ public class SchedulingFilterImplTest extends EasyMockTest { new UnusedResource(twoPorts, hostA), new ResourceRequest(twoPortTask, EMPTY))); assertEquals( - ImmutableSet.of(PORTS.veto(1)), + ImmutableSet.of(veto(PORTS, 1)), defaultFilter.filter( new UnusedResource(twoPorts, hostA), new ResourceRequest(threePortTask, EMPTY))); @@ -147,10 +148,10 @@ public class SchedulingFilterImplTest extends EasyMockTest { assertVetoes( makeTask(DEFAULT_CPUS + 1, DEFAULT_RAM + 1, DEFAULT_DISK + 1), hostA, - CPU.veto(1), DISK.veto(1), RAM.veto(1)); - assertVetoes(makeTask(DEFAULT_CPUS + 1, DEFAULT_RAM, DEFAULT_DISK), hostA, CPU.veto(1)); - assertVetoes(makeTask(DEFAULT_CPUS, DEFAULT_RAM + 1, DEFAULT_DISK), hostA, RAM.veto(1)); - assertVetoes(makeTask(DEFAULT_CPUS, DEFAULT_RAM, DEFAULT_DISK + 1), hostA, DISK.veto(1)); + veto(CPUS, 1), veto(DISK_MB, 1), veto(RAM_MB, 1)); + assertVetoes(makeTask(DEFAULT_CPUS + 1, DEFAULT_RAM, DEFAULT_DISK), hostA, veto(CPUS, 1)); + assertVetoes(makeTask(DEFAULT_CPUS, DEFAULT_RAM + 1, DEFAULT_DISK), hostA, veto(RAM_MB, 1)); + assertVetoes(makeTask(DEFAULT_CPUS, DEFAULT_RAM, DEFAULT_DISK + 1), hostA, veto(DISK_MB, 1)); } @Test @@ -419,10 +420,12 @@ public class SchedulingFilterImplTest extends EasyMockTest { control.replay(); int maxScore = VetoType.INSUFFICIENT_RESOURCES.getScore(); - assertEquals((int) (maxScore * 1.0 / CPU.getRange()), CPU.veto(1).getScore()); - assertEquals(maxScore, CPU.veto(CPU.getRange() * 10).getScore()); - assertEquals((int) (maxScore * 2.0 / RAM.getRange()), RAM.veto(2).getScore()); - assertEquals((int) (maxScore * 200.0 / DISK.getRange()), DISK.veto(200).getScore()); + assertEquals((int) (maxScore * 1.0 / CPUS.getScalingRange()), veto(CPUS, 1).getScore()); + assertEquals(maxScore, veto(CPUS, CPUS.getScalingRange() * 10).getScore()); + assertEquals((int) (maxScore * 2.0 / RAM_MB.getScalingRange()), veto(RAM_MB, 2).getScore()); + assertEquals( + (int) (maxScore * 200.0 / DISK_MB.getScalingRange()), + veto(DISK_MB, 200).getScore()); } @Test @@ -464,6 +467,12 @@ public class SchedulingFilterImplTest extends EasyMockTest { Veto.unsatisfiedLimit("denied")))); } + private static Veto veto(ResourceType resourceType, int excess) { + return Veto.insufficientResources( + resourceType.getAuroraName(), + SchedulingFilterImpl.scale(excess, resourceType.getScalingRange())); + } + private ITaskConfig checkConstraint( IHostAttributes hostAttributes, String constraintName,
