use of com.netflix.titus.master.eviction.service.quota.QuotaController in project titus-control-plane by Netflix.
the class JobQuotaController method mergeQuotaControllers.
@VisibleForTesting
static List<QuotaController<Job<?>>> mergeQuotaControllers(List<QuotaController<Job<?>>> previousControllers, Job<?> job, V3JobOperations jobOperations, EffectiveJobDisruptionBudgetResolver effectiveDisruptionBudgetResolver, TitusRuntime titusRuntime) {
List<QuotaController<Job<?>>> quotaControllers = new ArrayList<>();
DisruptionBudget effectiveBudget = effectiveDisruptionBudgetResolver.resolve(job);
if (effectiveBudget.getDisruptionBudgetRate() instanceof PercentagePerHourDisruptionBudgetRate) {
QuotaController<Job<?>> newController = mergeQuotaController(job, previousControllers, JobPercentagePerHourRelocationRateController.class, () -> JobPercentagePerHourRelocationRateController.newJobPercentagePerHourRelocationRateController(job, effectiveDisruptionBudgetResolver, titusRuntime));
quotaControllers.add(newController);
} else if (effectiveBudget.getDisruptionBudgetRate() instanceof RatePercentagePerIntervalDisruptionBudgetRate) {
QuotaController<Job<?>> newController = mergeQuotaController(job, previousControllers, JobPercentagePerIntervalRateController.class, () -> JobPercentagePerIntervalRateController.newJobPercentagePerIntervalRateController(job, effectiveDisruptionBudgetResolver, titusRuntime));
quotaControllers.add(newController);
} else if (effectiveBudget.getDisruptionBudgetRate() instanceof RatePerIntervalDisruptionBudgetRate) {
QuotaController<Job<?>> newController = mergeQuotaController(job, previousControllers, RatePerIntervalRateController.class, () -> RatePerIntervalRateController.newRatePerIntervalRateController(job, effectiveDisruptionBudgetResolver, titusRuntime));
quotaControllers.add(newController);
}
DisruptionBudgetPolicy policy = effectiveBudget.getDisruptionBudgetPolicy();
if (policy instanceof RelocationLimitDisruptionBudgetPolicy) {
QuotaController<Job<?>> newController = mergeQuotaController(job, previousControllers, TaskRelocationLimitController.class, () -> new TaskRelocationLimitController(job, jobOperations, effectiveDisruptionBudgetResolver));
quotaControllers.add(newController);
}
return quotaControllers;
}
use of com.netflix.titus.master.eviction.service.quota.QuotaController in project titus-control-plane by Netflix.
the class JobQuotaControllerTest method testMergeTaskRelocationLimitController.
@Test
public void testMergeTaskRelocationLimitController() {
// First version
Job<BatchJobExt> job = newBatchJob(10, budget(perTaskRelocationLimitPolicy(1), unlimitedRate(), Collections.emptyList()));
scheduleJob(job, 10);
List<QuotaController<Job<?>>> controllers = buildQuotaControllers(job, jobOperations, SelfJobDisruptionBudgetResolver.getInstance(), titusRuntime);
TaskRelocationLimitController controller = (TaskRelocationLimitController) controllers.get(0);
Task task = jobOperations.getTasks(job.getId()).get(0);
assertThat(controller.consume(task.getId()).isApproved()).isTrue();
jobComponentStub.killTask(task, false, false, V3JobOperations.Trigger.Eviction);
assertThat(controller.consume(task.getId()).isApproved()).isFalse();
Task replacement1 = jobComponentStub.getJobOperations().getTasks().stream().filter(t -> t.getOriginalId().equals(task.getId())).findFirst().get();
jobComponentStub.moveTaskToState(replacement1, TaskState.Started);
// Change job descriptor and consume some quota
Job<BatchJobExt> updatedJob = jobComponentStub.changeJob(exceptPolicy(job, perTaskRelocationLimitPolicy(3)));
List<QuotaController<Job<?>>> merged = mergeQuotaControllers(controllers, updatedJob, jobOperations, SelfJobDisruptionBudgetResolver.getInstance(), titusRuntime);
TaskRelocationLimitController updatedController = (TaskRelocationLimitController) merged.get(0);
// Evict replacement 1
assertThat(updatedController.consume(replacement1.getId()).isApproved()).isTrue();
jobComponentStub.killTask(replacement1, false, false, V3JobOperations.Trigger.Eviction);
Task replacement2 = jobComponentStub.getJobOperations().getTasks().stream().filter(t -> t.getOriginalId().equals(task.getId())).findFirst().get();
jobComponentStub.moveTaskToState(replacement2, TaskState.Started);
// Evict replacement 2
assertThat(updatedController.consume(replacement2.getId()).isApproved()).isTrue();
jobComponentStub.killTask(replacement2, false, false, V3JobOperations.Trigger.Eviction);
Task replacement3 = jobComponentStub.getJobOperations().getTasks().stream().filter(t -> t.getOriginalId().equals(task.getId())).findFirst().get();
jobComponentStub.moveTaskToState(replacement3, TaskState.Started);
assertThat(updatedController.consume(replacement3.getId()).isApproved()).isFalse();
}
use of com.netflix.titus.master.eviction.service.quota.QuotaController in project titus-control-plane by Netflix.
the class JobQuotaControllerTest method testMergePercentagePerHourDisruptionBudgetRateQuotaController.
@Test
public void testMergePercentagePerHourDisruptionBudgetRateQuotaController() {
// First version
Job<BatchJobExt> job = newBatchJob(10, budget(perTaskRelocationLimitPolicy(3), hourlyRatePercentage(50), Collections.emptyList()));
com.netflix.titus.api.model.reference.Reference jobReference = com.netflix.titus.api.model.reference.Reference.job(job.getId());
scheduleJob(job, 10);
List<QuotaController<Job<?>>> controllers = buildQuotaControllers(job, jobOperations, SelfJobDisruptionBudgetResolver.getInstance(), titusRuntime);
JobPercentagePerHourRelocationRateController controller = (JobPercentagePerHourRelocationRateController) controllers.get(0);
Task task = jobOperations.getTasks(job.getId()).get(0);
assertThat(controller.consume(task.getId()).isApproved()).isTrue();
assertThat(controller.getQuota(jobReference).getQuota()).isEqualTo(4);
// Change job descriptor and consume some quota
Job<BatchJobExt> updatedJob = jobComponentStub.changeJob(exceptRate(job, hourlyRatePercentage(80)));
List<QuotaController<Job<?>>> merged = mergeQuotaControllers(controllers, updatedJob, jobOperations, SelfJobDisruptionBudgetResolver.getInstance(), titusRuntime);
JobPercentagePerHourRelocationRateController updatedController = (JobPercentagePerHourRelocationRateController) merged.get(0);
assertThat(updatedController.getQuota(jobReference).getQuota()).isEqualTo(7);
}
use of com.netflix.titus.master.eviction.service.quota.QuotaController in project titus-control-plane by Netflix.
the class JobQuotaController method buildQuotaControllers.
@VisibleForTesting
static List<QuotaController<Job<?>>> buildQuotaControllers(Job<?> job, V3JobOperations jobOperations, EffectiveJobDisruptionBudgetResolver effectiveDisruptionBudgetResolver, TitusRuntime titusRuntime) {
List<QuotaController<Job<?>>> quotaControllers = new ArrayList<>();
DisruptionBudget effectiveBudget = effectiveDisruptionBudgetResolver.resolve(job);
if (effectiveBudget.getDisruptionBudgetRate() instanceof PercentagePerHourDisruptionBudgetRate) {
quotaControllers.add(JobPercentagePerHourRelocationRateController.newJobPercentagePerHourRelocationRateController(job, effectiveDisruptionBudgetResolver, titusRuntime));
} else if (effectiveBudget.getDisruptionBudgetRate() instanceof RatePercentagePerIntervalDisruptionBudgetRate) {
quotaControllers.add(JobPercentagePerIntervalRateController.newJobPercentagePerIntervalRateController(job, effectiveDisruptionBudgetResolver, titusRuntime));
} else if (effectiveBudget.getDisruptionBudgetRate() instanceof RatePerIntervalDisruptionBudgetRate) {
quotaControllers.add(RatePerIntervalRateController.newRatePerIntervalRateController(job, effectiveDisruptionBudgetResolver, titusRuntime));
}
DisruptionBudgetPolicy policy = effectiveBudget.getDisruptionBudgetPolicy();
if (policy instanceof RelocationLimitDisruptionBudgetPolicy) {
quotaControllers.add(new TaskRelocationLimitController(job, jobOperations, effectiveDisruptionBudgetResolver));
}
return quotaControllers;
}
use of com.netflix.titus.master.eviction.service.quota.QuotaController in project titus-control-plane by Netflix.
the class JobQuotaControllerTest method testMergeRatePerIntervalDisruptionBudgetRateQuotaController.
@Test
public void testMergeRatePerIntervalDisruptionBudgetRateQuotaController() {
// First version
Job<BatchJobExt> job = newBatchJob(10, budget(perTaskRelocationLimitPolicy(3), ratePerInterval(60_000, 5), Collections.emptyList()));
com.netflix.titus.api.model.reference.Reference jobReference = com.netflix.titus.api.model.reference.Reference.job(job.getId());
scheduleJob(job, 10);
List<QuotaController<Job<?>>> controllers = buildQuotaControllers(job, jobOperations, SelfJobDisruptionBudgetResolver.getInstance(), titusRuntime);
RatePerIntervalRateController controller = (RatePerIntervalRateController) controllers.get(0);
Task task = jobOperations.getTasks(job.getId()).get(0);
assertThat(controller.consume(task.getId()).isApproved()).isTrue();
assertThat(controller.getQuota(jobReference).getQuota()).isEqualTo(4);
// Change job descriptor and consume some quota
Job<BatchJobExt> updatedJob = jobComponentStub.changeJob(exceptRate(job, ratePerInterval(30_000, 5)));
List<QuotaController<Job<?>>> merged = mergeQuotaControllers(controllers, updatedJob, jobOperations, SelfJobDisruptionBudgetResolver.getInstance(), titusRuntime);
RatePerIntervalRateController updatedController = (RatePerIntervalRateController) merged.get(0);
assertThat(updatedController.getQuota(jobReference).getQuota()).isEqualTo(4);
}
Aggregations