/* * Copyright 2015 Netflix, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.netflix.fenzo; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class RandomTaskGenerator { public static class TaskType { private final double coreSize; private final double ratioOfTasks; private final long minRunDurationMillis; private final long maxRunDurationMillis; public TaskType(double coreSize, double ratioOfTasks, long minRunDurationMillis, long maxRunDurationMillis) { this.coreSize = coreSize; this.ratioOfTasks = ratioOfTasks; this.minRunDurationMillis = minRunDurationMillis; this.maxRunDurationMillis = maxRunDurationMillis; } public double getCoreSize() { return coreSize; } public double getRatioOfTasks() { return ratioOfTasks; } public long getMinRunDurationMillis() { return minRunDurationMillis; } public long getMaxRunDurationMillis() { return maxRunDurationMillis; } } public static class GeneratedTask implements TaskRequest, Comparable<GeneratedTask> { private final TaskRequest taskRequest; private final long runUntilMillis; private final long runtimeMillis; private String hostname; private AssignedResources assignedResources=null; public GeneratedTask(final TaskRequest taskRequest, final long runtimeMillis, final long runUntilMillis) { this.taskRequest = taskRequest; this.runUntilMillis = runUntilMillis; this.runtimeMillis = runtimeMillis; } public long getRunUntilMillis() { return runUntilMillis; } public long getRuntimeMillis() { return runtimeMillis; } @Override public String getId() { return taskRequest.getId(); } @Override public String taskGroupName() { return ""; } @Override public double getCPUs() { return taskRequest.getCPUs(); } @Override public double getMemory() { return taskRequest.getMemory(); } @Override public double getNetworkMbps() { return 0.0; } @Override public double getDisk() { return taskRequest.getDisk(); } @Override public int getPorts() { return taskRequest.getPorts(); } @Override public Map<String, Double> getScalarRequests() { return null; } @Override public List<? extends ConstraintEvaluator> getHardConstraints() { return taskRequest.getHardConstraints(); } @Override public List<? extends VMTaskFitnessCalculator> getSoftConstraints() { return taskRequest.getSoftConstraints(); } @Override public void setAssignedResources(AssignedResources assignedResources) { this.assignedResources = assignedResources; } @Override public AssignedResources getAssignedResources() { return assignedResources; } @Override public Map<String, NamedResourceSetRequest> getCustomNamedResources() { return Collections.emptyMap(); } @Override public int compareTo(GeneratedTask o) { if(o==null) return -1; return Long.compare(runUntilMillis, o.runUntilMillis); } public String getHostname() { return hostname; } public void setHostname(String hostname) { this.hostname = hostname; } } private final List<TaskType> taskTypes; private final double memoryPerCore=1000.0; private final int minTasksPerCoreSizePerBatch; private final long interBatchIntervalMillis; private double minRatio; private final BlockingQueue<GeneratedTask> taskQueue; RandomTaskGenerator(BlockingQueue<GeneratedTask> taskQueue, long interBatchIntervalMillis, int minTasksPerCoreSizePerBatch, List<TaskType> taskTypes) { if(taskTypes==null || taskTypes.isEmpty()) throw new IllegalArgumentException(); this.taskQueue = taskQueue; this.interBatchIntervalMillis = interBatchIntervalMillis; this.minTasksPerCoreSizePerBatch = minTasksPerCoreSizePerBatch; minRatio=Double.MAX_VALUE; this.taskTypes = taskTypes; for(TaskType j: taskTypes) if(j.getRatioOfTasks()<minRatio) minRatio = j.getRatioOfTasks(); } void start() { new ScheduledThreadPoolExecutor(1).scheduleWithFixedDelay(new Runnable() { @Override public void run() { long now = System.currentTimeMillis(); int numTasksGenerated=0; for(TaskType taskType: taskTypes) { int numTasks = (int) (taskType.getRatioOfTasks()*minTasksPerCoreSizePerBatch/minRatio); for(int t=0; t<numTasks; t++) { long runtime = getRuntime(taskType.minRunDurationMillis, taskType.maxRunDurationMillis); taskQueue.offer(new GeneratedTask( TaskRequestProvider.getTaskRequest(taskType.coreSize, taskType.coreSize*memoryPerCore, 1), runtime, now+runtime )); numTasksGenerated++; } } System.out.println(" " + numTasksGenerated + " tasks generated"); } }, interBatchIntervalMillis, interBatchIntervalMillis, TimeUnit.MILLISECONDS); } List<GeneratedTask> getTasks() { List<GeneratedTask> tasks = new ArrayList<>(); long now = System.currentTimeMillis(); for(TaskType taskType: taskTypes) { int numTasks = (int) (taskType.getRatioOfTasks()*minTasksPerCoreSizePerBatch/minRatio); for(int t=0; t<numTasks; t++) { long runtime = getRuntime(taskType.minRunDurationMillis, taskType.maxRunDurationMillis); tasks.add(new GeneratedTask( TaskRequestProvider.getTaskRequest(taskType.coreSize, taskType.coreSize*memoryPerCore, 1), runtime, now+runtime )); } } return tasks; } private long getRuntime(long minRunDurationMillis, long maxRunDurationMillis) { return minRunDurationMillis + (long)(Math.random() * (double)(maxRunDurationMillis-minRunDurationMillis)); } }