/* * Copyright (c) Fabien Hermenier * * This file is part of Entropy. * * Entropy is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Entropy is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Entropy. If not, see <http://www.gnu.org/licenses/>. */ package entropy.plan.partitioner; import java.util.ArrayList; import java.util.List; import entropy.configuration.Configuration; import entropy.configuration.Configurations; import entropy.configuration.ConfigurationsException; import entropy.configuration.ManagedElementSet; import entropy.configuration.Node; import entropy.configuration.VirtualMachine; import entropy.plan.PlanException; import entropy.plan.SolutionStatistics; import entropy.plan.SolvingStatistics; import entropy.plan.TimedReconfigurationPlan; import entropy.plan.choco.ChocoCustomRP; import entropy.plan.durationEvaluator.DurationEvaluator; import entropy.vjob.BasicVJob; import entropy.vjob.PlacementConstraint; import entropy.vjob.VJob; /** * Wrap a solving process into a Thread. * * @author Fabien Hermenier */ public class PlanThread extends Thread { private ChocoCustomRP m; private ManagedElementSet<VirtualMachine> run; private ManagedElementSet<VirtualMachine> wait; private ManagedElementSet<VirtualMachine> sleep; private ManagedElementSet<VirtualMachine> stop; private ManagedElementSet<Node> on; private ManagedElementSet<Node> off; private List<VJob> queue; private Configuration cfg; private TimedReconfigurationPlan plan; private PlanException ex = null; private boolean repair; private int timeout; private SolvingStatistics solvingStats; private List<SolutionStatistics> solutions; public void setRepairMode(boolean mode) { repair = mode; } public void setTimeout(int t) { this.timeout = t; } /** * Compute a new DefaultTimedReconfigurationPlan that satisfy all the constraints applied to the model. * * @param part The partition to use * @param eval the duration estimation of the action * @param src The source configuration. It must be viable. * @param run The set of virtual machines that must be running at the end of the process * @param wait The set of virtual machines that must be waiting at the end of the process * @param sleep The set of virtual machines that must be sleeping at the end of the process * @param stop The set of virtual machines that must be terminated at the end of the process * @param on The set of nodes that must be online at the end of the process * @param off The set of nodes that must be offline at the end of the process */ public PlanThread(Partition part, DurationEvaluator eval, Configuration src, ManagedElementSet<VirtualMachine> run, ManagedElementSet<VirtualMachine> wait, ManagedElementSet<VirtualMachine> sleep, ManagedElementSet<VirtualMachine> stop, ManagedElementSet<Node> on, ManagedElementSet<Node> off) throws ConfigurationsException, PlanException { //Divide the original configuration cfg = Configurations.subConfiguration(src, part.getVirtualMachines(), part.getNodes()); solutions = new ArrayList<SolutionStatistics>(); //Divide the vms this.run = run.clone(); this.wait = wait.clone(); this.sleep = sleep.clone(); this.stop = stop.clone(); this.on = on.clone(); this.off = off.clone(); this.run.retainAll(part.getVirtualMachines()); this.wait.retainAll(part.getVirtualMachines()); this.sleep.retainAll(part.getVirtualMachines()); this.stop.retainAll(part.getVirtualMachines()); this.off.retainAll(part.getNodes()); this.on.retainAll(part.getNodes()); m = new ChocoCustomRP(eval); VJob vj = new BasicVJob(getRunID()); for (PlacementConstraint x : part.getConstraints()) { vj.addConstraint(x); } queue = new ArrayList<VJob>(); queue.add(vj); } /** * Get statistics of the computed solutions * * @return a list of statistics thatmay be empty */ public List<SolutionStatistics> getSolutionsStatistics() { if (m != null) { return m.getSolutionsStatistics(); } return solutions; } /** * Get the statistics about the solving process * * @return some statistics */ public SolvingStatistics getSolvingStatistics() { if (m != null) { return m.getSolvingStatistics(); } return solvingStats; } @Override public void run() { try { m.setRepairMode(repair); m.setTimeLimit(timeout); plan = m.compute(cfg, run, wait, sleep, stop, on, off, queue); //Copy statistics to liberate memory more easily (no more references to the problem) solvingStats = m.getSolvingStatistics().clone(); solutions.clear(); for (SolutionStatistics st : m.getSolutionsStatistics()) { solutions.add(st.clone()); } //Plan.logger.debug(getRunID() + " " + plan.toString()); m = null; } catch (PlanException e) { this.ex = e; } finally { m = null; } } /** * Get the exception that may occurred during the solving process * * @return an exception or {@code null} if no exception occurred */ public PlanException getException() { return ex; } /** * Get the computed plan * * @return a plan or {@code null} if no plan was computed */ public TimedReconfigurationPlan getResultingPlan() { return plan; } /** * Get the id of the solving process. * * @return a String */ public String getRunID() { return new StringBuilder("Partition ").toString(); } @Override public String toString() { return getRunID(); } }