/** * Copyright (C) 2001-2017 by RapidMiner and the contributors * * Complete list of developers available at our web site: * * http://rapidminer.com * * This program is free software: you can redistribute it and/or modify it under the terms of the * GNU Affero General Public License as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * This program 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 * Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License along with this program. * If not, see http://www.gnu.org/licenses/. */ package com.rapidminer.studio.concurrency.internal; import java.util.List; import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.Future; import com.rapidminer.Process; import com.rapidminer.RapidMiner; import com.rapidminer.operator.IOContainer; import com.rapidminer.operator.Operator; import com.rapidminer.operator.OperatorException; import com.rapidminer.operator.UserError; import com.rapidminer.studio.concurrency.internal.util.BackgroundExecution; import com.rapidminer.studio.concurrency.internal.util.BackgroundExecutionServiceListener; import com.rapidminer.studio.concurrency.internal.util.ProcessBackgroundExecution; import com.rapidminer.studio.internal.ParameterServiceRegistry; /** * Interface for the concurrent process and operator execution service. * <p> * Note that this part of the API is only temporary and might be removed in future versions again. * </p> * * @author Marco Boeck * @since 7.4 */ public interface ConcurrencyExecutionService { /** * Calculates the recommended batch size for parallel operators. Use when deciding how many * tasks to submit to * {@link ConcurrencyExecutionService#executeOperatorTasks(Operator, java.util.List)} * simultaneously. * * @return the recommended batch size. Will never be less than the user setting of * {@link RapidMiner#PROPERTY_RAPIDMINER_GENERAL_NUMBER_OF_THREADS} * @since 7.5 */ public static int getRecommendedConcurrencyBatchSize() { String threadSettingString = ParameterServiceRegistry.INSTANCE .getParameterValue(RapidMiner.PROPERTY_RAPIDMINER_GENERAL_NUMBER_OF_THREADS); int threadSetting = 0; try { threadSetting = Integer.parseInt(threadSettingString); } catch (NumberFormatException e) { // do nothing } if (threadSetting == 0) { threadSetting = Math.max(1, Runtime.getRuntime().availableProcessors() - 1); } return Math.max(2_000, threadSetting); } /** * This method executes the given process in the background. This method does * <strong>not</strong> block. * </p> * * @param process * The process to be executed in the background */ void executeProcess(Process process) throws UserError; /** * This method executes a process from the repository under certain input and macros. It can be * used to run entire processes in the background from a process. * <p> * This method does <strong>not</strong> block. * </p> * * @param process * @param container * @param macroSettings */ void executeProcess(Process process, IOContainer container, Map<String, String> macroSettings) throws UserError; /** * This method will prepare an operator with subprocesses, that should be performed in parallel * as specified by the given {@link Callable}. The operator will be added to an otherwise empty * {@link BackgroundExecutionProcess}, that will capture all the side effects. If * synchronizeSideEffects is true, these side effects will be merged back into the * parentProcess. * * @param <T> * * @param parentProcess * The process which contains the parallelized operator * @param clonedOperator * A clone of this parallelized operator * @param applyCount * The apply count for this current parallelized version * @param synchronizeSideEffects * Whether side effects should be merged, usually only during last iteration * @param task * The actual sub task of the operator to execute * @return */ <V, T> Callable<V> prepareOperatorTask(Process parentProcess, Operator clonedOperator, int applyCount, boolean synchronizeSideEffects, Callable<V> task); /** * Executes the tasks for the given operator. * * @param operator * the operator which executes the given tasks * @param tasks * the tasks which should be executed * @return the execution result * @throws OperatorException * if something goes wrong during the task execution */ <T> List<T> executeOperatorTasks(Operator operator, List<Callable<T>> tasks) throws OperatorException; /** * Submits the task for the given operator for execution. * * @param operator * the operator which executes the given task * @param task * the task which should be executed * @return a future which can be used to later access the result * @since 7.3 */ <T> Future<T> submitOperatorTask(Operator operator, Callable<T> task); /** * Waits for the results of the given {@link Future}s, returning their results upon completion. * <p> * The method blocks until all {@code Future}s have their results. * <p> * This is an advanced method which should only be used if you know what you are doing. Usage of * {@link #call(List)} is recommended instead. * * @param <T> * the type of the values returned from the futures * @param operator * the operator which executes the given tasks * @param futures * the {@link Future}s for which their results should be collected * @return a list containing the results of the futures * @throws OperatorException * if something goes wrong during the task execution * @since 7.3 */ <T> List<T> collectResults(Operator operator, List<Future<T>> futures) throws OperatorException; /** * This method removes the task from the list of currently executed things. If all tasks are * removed the the corresponding UI element will be removed as well. * * @param parentProcess * @param operatorName * @param applyCount */ void removeOperatorTask(Process parentProcess, String operatorName, int applyCount); /** * This copies the list of background executions and returns the copy. * * @return */ List<BackgroundExecution> getExecutions(); /** * This method will execute the given {@link Callable} by calling it's run method within the * current thread. * * @param callable * @throws Exception */ <T> T executeBlockingTask(Callable<T> callable) throws Exception; /** * This stops the execution of a given process execution in the background. * * @param execution */ void stopProcessExecution(ProcessBackgroundExecution execution); /** * This drops the execution from the manageable data structures. Please notice, that this will * not stop nor release any resources. To stop execution, you will need to call stopExecution * before. * * @param execution */ void removeProcessExecution(ProcessBackgroundExecution execution); /** * The provided listener will be notified if any background execution is added or removed * * @param listener * This listener is being added to the listener pool */ void addListener(BackgroundExecutionServiceListener listener); /** * Notifies every listener that a new process has been added to the executions */ void newProcessEvent(BackgroundExecution execution); /** * Notifies every listener that a process has been removed from the executions */ void removedProcessEvent(BackgroundExecution execution); }