com.netflix.fenzo.TaskTracker Maven / Gradle / Ivy
/*
* 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 com.netflix.fenzo.queues.QueuableTask;
import com.netflix.fenzo.queues.TaskQueueException;
import com.netflix.fenzo.queues.UsageTrackedQueue;
import com.netflix.fenzo.sla.ResAllocs;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* Class to keep track of task assignments.
*/
public class TaskTracker {
static class TaskGroupUsage implements ResAllocs {
private final String taskGroupName;
private double cores=0.0;
private double memory=0.0;
private double networkMbps=0.0;
private double disk=0.0;
private TaskGroupUsage(String taskGroupName) {
this.taskGroupName = taskGroupName;
}
@Override
public String getTaskGroupName() {
return taskGroupName;
}
@Override
public double getCores() {
return cores;
}
@Override
public double getMemory() {
return memory;
}
@Override
public double getNetworkMbps() {
return networkMbps;
}
@Override
public double getDisk() {
return disk;
}
void addUsage(TaskRequest task) {
cores += task.getCPUs();
memory += task.getMemory();
networkMbps += task.getNetworkMbps();
disk += task.getDisk();
}
void subtractUsage(TaskRequest task) {
cores -= task.getCPUs();
if(cores < 0.0) {
logger.warn("correcting cores usage <0.0");
cores=0.0;
}
memory -= task.getMemory();
if(memory<0.0) {
logger.warn("correcting memory usage<0.0");
memory=0.0;
}
networkMbps -= task.getNetworkMbps();
if(networkMbps<0.0) {
logger.warn("correcting networkMbps usage<0.0");
networkMbps=0.0;
}
disk -= task.getDisk();
if(disk<0.0) {
logger.warn("correcting disk usage<0.0");
disk=0.0;
}
}
}
// TODO move this class out into its own class instead of being an inner class
/**
* An active task in the scheduler.
*/
public static class ActiveTask {
private TaskRequest taskRequest;
private AssignableVirtualMachine avm;
public ActiveTask(TaskRequest taskRequest, AssignableVirtualMachine avm) {
this.taskRequest = taskRequest;
this.avm = avm;
}
/**
* Get the task request object associated with the active task.
*
* @return the task request object
*/
public TaskRequest getTaskRequest() {
return taskRequest;
}
/**
* Get the totals resource offers associated with the host on which the task is active.
*
* @return the total resource offers for the host
*/
public VirtualMachineLease getTotalLease() {
return avm.getCurrTotalLease();
}
}
private static final Logger logger = LoggerFactory.getLogger(TaskTracker.class);
private final Map runningTasks = new HashMap<>();
private final Map assignedTasks = new HashMap<>();
private final Map taskGroupUsages = new HashMap<>();
private UsageTrackedQueue usageTrackedQueue = null;
// package scoped
TaskTracker() {
}
/* package */ void setUsageTrackedQueue(UsageTrackedQueue t) {
usageTrackedQueue = t;
}
boolean addRunningTask(TaskRequest request, AssignableVirtualMachine avm) {
final boolean added = runningTasks.put(request.getId(), new ActiveTask(request, avm)) == null;
if(added) {
addUsage(request);
if (usageTrackedQueue != null && request instanceof QueuableTask)
try {
usageTrackedQueue.launchTask((QueuableTask)request);
} catch (TaskQueueException e) {
// We don't expect this to happen since we call this only outside scheduling iteration
logger.warn("Unexpected: " + e.getMessage());
}
}
return added;
}
boolean removeRunningTask(String taskId) {
final ActiveTask removed = runningTasks.remove(taskId);
if(removed != null) {
final TaskRequest task = removed.getTaskRequest();
final TaskGroupUsage usage = taskGroupUsages.get(task.taskGroupName());
if(usage==null)
logger.warn("Unexpected to not find usage for task group " + task.taskGroupName() +
" to unqueueTask usage of task " + task.getId());
else
usage.subtractUsage(task);
if (usageTrackedQueue != null && removed.getTaskRequest() instanceof QueuableTask)
try {
final QueuableTask queuableTask = (QueuableTask) removed.getTaskRequest();
usageTrackedQueue.removeTask(queuableTask.getId(), queuableTask.getQAttributes());
} catch (TaskQueueException e) {
// We don't expect this to happen since we call this only outside scheduling iteration
logger.warn("Unexpected: " + e.getMessage());
}
}
return removed != null;
}
Map getAllRunningTasks() {
return Collections.unmodifiableMap(runningTasks);
}
boolean addAssignedTask(TaskRequest request, AssignableVirtualMachine avm) {
final boolean assigned = assignedTasks.put(request.getId(), new ActiveTask(request, avm)) == null;
if(assigned) {
addUsage(request);
if (usageTrackedQueue != null && request instanceof QueuableTask)
try {
usageTrackedQueue.assignTask((QueuableTask) request);
} catch (TaskQueueException e) {
// We don't expect this to happen since we call this only from within a scheduling iteration
logger.warn("Unexpected: " + e.getMessage());
}
}
return assigned;
}
private void addUsage(TaskRequest request) {
TaskGroupUsage usage = taskGroupUsages.get(request.taskGroupName());
if(usage==null) {
taskGroupUsages.put(request.taskGroupName(), new TaskGroupUsage(request.taskGroupName()));
usage = taskGroupUsages.get(request.taskGroupName());
}
usage.addUsage(request);
}
void clearAssignedTasks() {
for(ActiveTask t: assignedTasks.values())
taskGroupUsages.get(t.getTaskRequest().taskGroupName()).subtractUsage(t.getTaskRequest());
assignedTasks.clear();
}
Map getAllAssignedTasks() {
return Collections.unmodifiableMap(assignedTasks);
}
TaskGroupUsage getUsage(String taskGroupName) {
return taskGroupUsages.get(taskGroupName);
}
void setTotalResources(Map totalResourcesMap) {
if (usageTrackedQueue != null)
usageTrackedQueue.setTotalResources(totalResourcesMap);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy