All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.netflix.fenzo.TaskTracker Maven / Gradle / Ivy

There is a newer version: 1.0.1
Show newest version
/*
 * 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