Search in sources :

Example 1 with TaskContext

use of org.ow2.proactive.scheduler.task.context.TaskContext in project scheduling by ow2-proactive.

the class TaskLauncher method doTask.

public void doTask(ExecutableContainer executableContainer, TaskResult[] previousTasksResults, TaskTerminateNotification terminateNotification, String terminateNotificationNodeURL, boolean taskRecoverable) {
    TaskResultImpl taskResult;
    WallTimer wallTimer = null;
    TaskContext context = null;
    Stopwatch taskStopwatchForFailures = null;
    TaskDataspaces dataspaces = null;
    try {
        taskStarted.set(true);
        logger.info("Task started " + taskId.getJobId().getReadableName() + " : " + taskId.getReadableName());
        this.taskKiller = this.replaceTaskKillerWithDoubleTimeoutValueIfRunAsMe(executableContainer.isRunAsUser());
        wallTimer = new WallTimer(initializer.getWalltime(), taskKiller);
        taskStopwatchForFailures = Stopwatch.createUnstarted();
        taskLauncherRebinder = new TaskLauncherRebinder(taskId, terminateNotificationNodeURL, taskRecoverable);
        addShutdownHook();
        // lock the cache space cleaning mechanism
        DataSpaceNodeConfigurationAgent.lockCacheSpaceCleaning();
        dataspaces = factory.createTaskDataspaces(taskId, initializer.getNamingService(), executableContainer.isRunAsUser());
        File taskLogFile = taskLogger.createFileAppender(dataspaces.getScratchFolder());
        progressFileReader.start(dataspaces.getScratchFolder(), taskId);
        context = new TaskContext(executableContainer, initializer, previousTasksResults, new NodeDataSpacesURIs(dataspaces.getScratchURI(), dataspaces.getCacheURI(), dataspaces.getInputURI(), dataspaces.getOutputURI(), dataspaces.getUserURI(), dataspaces.getGlobalURI()), progressFileReader.getProgressFile().toString(), getHostname(), decrypter);
        File workingDir = getTaskWorkingDir(context, dataspaces);
        logger.info("Task working dir: " + workingDir);
        logger.info("Cache space: " + context.getNodeDataSpaceURIs().getCacheURI());
        logger.info("Input space: " + context.getNodeDataSpaceURIs().getInputURI());
        logger.info("Output space: " + context.getNodeDataSpaceURIs().getOutputURI());
        logger.info("User space: " + context.getNodeDataSpaceURIs().getUserURI());
        logger.info("Global space: " + context.getNodeDataSpaceURIs().getGlobalURI());
        logger.info("Scheduler rest url: " + context.getSchedulerRestUrl());
        wallTimer.start();
        // should handle interrupt
        dataspaces.copyInputDataToScratch(initializer.getFilteredInputFiles(fileSelectorsFilters(context)));
        if (decrypter != null) {
            decrypter.setCredentials(executableContainer.getCredentials());
        }
        TaskExecutor taskExecutor = factory.createTaskExecutor(workingDir);
        taskStopwatchForFailures.start();
        taskResult = taskExecutor.execute(context, taskLogger.getOutputSink(), taskLogger.getErrorSink());
        taskStopwatchForFailures.stop();
        // by the time the task finishes, the scheduler might have had a
        // transient failure, so we need to make sure that the placeholder
        // for the task's result still exists, or get the new place for
        // the result if it does not exist anymore.
        TaskTerminateNotification rebindedTerminateNotification = taskLauncherRebinder.makeSureSchedulerIsConnected(terminateNotification);
        switch(taskKiller.getStatus()) {
            case WALLTIME_REACHED:
                taskResult = getWalltimedTaskResult(context, taskStopwatchForFailures);
                sendResultToScheduler(rebindedTerminateNotification, taskResult);
                return;
            case KILLED_MANUALLY:
                // killed by Scheduler, no need to send results back
                return;
        }
        dataspaces.copyScratchDataToOutput(initializer.getFilteredOutputFiles(fileSelectorsFilters(context, taskResult)));
        wallTimer.stop();
        copyTaskLogsToUserSpace(taskLogFile, dataspaces);
        taskResult.setLogs(taskLogger.getLogs());
        sendResultToScheduler(rebindedTerminateNotification, taskResult);
    } catch (Throwable taskFailure) {
        if (wallTimer != null) {
            wallTimer.stop();
        }
        switch(taskKiller.getStatus()) {
            case WALLTIME_REACHED:
                taskResult = getWalltimedTaskResult(context, taskStopwatchForFailures);
                sendResultToScheduler(terminateNotification, taskResult);
                break;
            case KILLED_MANUALLY:
                // killed by Scheduler, no need to send results back
                return;
            default:
                logger.info("Failed to execute task", taskFailure);
                long elapsedTime = 0;
                if (taskStopwatchForFailures != null) {
                    elapsedTime = taskStopwatchForFailures.elapsed(TimeUnit.MILLISECONDS);
                }
                taskFailure.printStackTrace(taskLogger.getErrorSink());
                Map<String, byte[]> serializedVariables = extractVariablesFromContext(context);
                taskResult = new TaskResultImpl(taskId, taskFailure, taskLogger.getLogs(), elapsedTime);
                taskResult.setPropagatedVariables(serializedVariables);
                sendResultToScheduler(terminateNotification, taskResult);
        }
    } finally {
        try {
            progressFileReader.stop();
            taskLogger.close();
            if (dataspaces != null) {
                dataspaces.close();
            }
            // unlocks the cache space cleaning thread
            DataSpaceNodeConfigurationAgent.unlockCacheSpaceCleaning();
            removeShutdownHook();
        } finally {
            terminate();
        }
    }
}
Also used : TaskTerminateNotification(org.ow2.proactive.scheduler.common.TaskTerminateNotification) TaskExecutor(org.ow2.proactive.scheduler.task.executors.TaskExecutor) TaskContext(org.ow2.proactive.scheduler.task.context.TaskContext) TaskDataspaces(org.ow2.proactive.scheduler.task.data.TaskDataspaces) Stopwatch(com.google.common.base.Stopwatch) WallTimer(org.ow2.proactive.scheduler.task.utils.WallTimer) NodeDataSpacesURIs(org.ow2.proactive.scheduler.task.context.NodeDataSpacesURIs) File(java.io.File) Map(java.util.Map)

Example 2 with TaskContext

use of org.ow2.proactive.scheduler.task.context.TaskContext in project scheduling by ow2-proactive.

the class TaskContextVariableExtractor method extractVariablesThirdPartyCredentialsAndSystemEnvironmentVariables.

/**
 * Retrieve all third party credential variables in a map.
 *
 * @param taskContext all information to extract third party credentials is here.
 *
 * @return map containing thirdPartyCredentials
 */
public Map<String, String> extractVariablesThirdPartyCredentialsAndSystemEnvironmentVariables(TaskContext taskContext) {
    ForkEnvironment forkEnvironment = taskContext.getInitializer().getForkEnvironment();
    Map<String, Serializable> variables = new HashMap<>();
    try {
        variables = extractAllVariables(taskContext, null, "");
    } catch (IOException | ClassNotFoundException e) {
        logger.error(ERROR_READING_VARIABLES, e);
    }
    Map<String, String> thirdPartyCredentials = new HashMap<>();
    try {
        thirdPartyCredentials = forkedTaskVariablesManager.extractThirdPartyCredentials(taskContext);
    } catch (Exception e) {
        logger.error(ERROR_READING_VARIABLES, e);
    }
    HashMap<String, Serializable> systemEnvironmentVariables = new HashMap<String, Serializable>(System.getenv());
    systemEnvironmentVariables.putAll(variables);
    systemEnvironmentVariables.putAll(thirdPartyCredentials);
    return VariableSubstitutor.filterAndUpdate(forkEnvironment.getSystemEnvironment(), systemEnvironmentVariables);
}
Also used : Serializable(java.io.Serializable) HashMap(java.util.HashMap) IOException(java.io.IOException) ForkEnvironment(org.ow2.proactive.scheduler.common.task.ForkEnvironment) IOException(java.io.IOException)

Example 3 with TaskContext

use of org.ow2.proactive.scheduler.task.context.TaskContext in project scheduling by ow2-proactive.

the class TaskContextVariableExtractor method extractSystemVariables.

/**
 * Extract default scheduller context variables, for a complete list see the documentation.
 * https://doc.activeeon.com/latest/user/ProActiveUserGuide.html#_proactive_system_variables
 *
 * @param taskContext object that contains job information to extract the desired variables.
 * @return map containing variables with values set.
 */
private Map<String, Serializable> extractSystemVariables(TaskContext taskContext, String nodesFile) {
    TaskLauncherInitializer initializer = taskContext.getInitializer();
    Map<String, Serializable> variables = new HashMap<>();
    variables.put(SchedulerVars.PA_JOB_ID.toString(), initializer.getTaskId().getJobId().value());
    variables.put(SchedulerVars.PA_JOB_NAME.toString(), initializer.getTaskId().getJobId().getReadableName());
    variables.put(SchedulerVars.PA_TASK_ID.toString(), initializer.getTaskId().value());
    variables.put(SchedulerVars.PA_TASK_NAME.toString(), initializer.getTaskId().getReadableName());
    variables.put(SchedulerVars.PA_TASK_ITERATION.toString(), initializer.getIterationIndex());
    variables.put(SchedulerVars.PA_TASK_REPLICATION.toString(), initializer.getReplicationIndex());
    variables.put(SchedulerVars.PA_TASK_PROGRESS_FILE.toString(), taskContext.getProgressFilePath());
    variables.put(SchedulerVars.PA_SCHEDULER_HOME.toString(), taskContext.getSchedulerHome());
    variables.put(SchedulerVars.PA_USER.toString(), initializer.getJobOwner());
    variables.put(SchedulerVars.PA_NODESFILE.toString(), nodesFile);
    variables.put(SchedulerVars.PA_NODESNUMBER.toString(), taskContext.getOtherNodesURLs().size() + 1);
    variables.put(SchedulerVars.PA_SCHEDULER_REST_URL.toString(), initializer.getSchedulerRestUrl());
    variables.put(SchedulerVars.PA_CATALOG_REST_URL.toString(), initializer.getCatalogRestUrl());
    return variables;
}
Also used : Serializable(java.io.Serializable) HashMap(java.util.HashMap) TaskLauncherInitializer(org.ow2.proactive.scheduler.task.TaskLauncherInitializer)

Example 4 with TaskContext

use of org.ow2.proactive.scheduler.task.context.TaskContext in project scheduling by ow2-proactive.

the class ForkedProcessBuilderCreator method executeForkEnvironmentScriptAndExtractVariables.

private ScriptResult executeForkEnvironmentScriptAndExtractVariables(TaskContext context, PrintStream outputSink, PrintStream errorSink, OSProcessBuilder processBuilder) throws Exception {
    ScriptResult forkEnvironmentScriptResult = null;
    ForkEnvironment forkEnvironment = context.getInitializer().getForkEnvironment();
    if (forkEnvironment != null) {
        if (forkEnvironment.getEnvScript() != null) {
            if (!context.getInitializer().isAuthorizedForkEnvironmentScript()) {
                throw new SecurityException("Unauthorized fork environment script: " + System.getProperty("line.separator") + forkEnvironment.getEnvScript().fetchScript());
            }
            forkEnvironmentScriptResult = forkEnvironmentScriptExecutor.executeForkEnvironmentScript(context, outputSink, errorSink);
        }
        try {
            processBuilder.environment().putAll(// by existing environment variables, variables and credentials
            taskContextVariableExtractor.extractVariablesThirdPartyCredentialsAndSystemEnvironmentVariables(context));
        } catch (IllegalArgumentException processEnvironmentReadOnly) {
            throw new IllegalStateException("Cannot use runAsMe mode and set system environment properties", processEnvironmentReadOnly);
        }
    }
    return forkEnvironmentScriptResult;
}
Also used : ScriptResult(org.ow2.proactive.scripting.ScriptResult) ForkEnvironment(org.ow2.proactive.scheduler.common.task.ForkEnvironment)

Example 5 with TaskContext

use of org.ow2.proactive.scheduler.task.context.TaskContext in project scheduling by ow2-proactive.

the class ForkedTaskExecutor method execute.

@Override
public TaskResultImpl execute(TaskContext context, PrintStream outputSink, PrintStream errorSink) {
    CookieBasedProcessTreeKiller taskProcessTreeKiller = null;
    Process process = null;
    ProcessStreamsReader processStreamsReader = null;
    File serializedContext = null;
    try {
        if (!workingDir.exists()) {
            FileUtils.forceMkdir(workingDir);
        }
        serializedContext = taskContextSerializer.serializeContext(context, workingDir);
        OSProcessBuilder processBuilder = forkedJvmProcessBuilderCreator.createForkedProcessBuilder(context, serializedContext, outputSink, errorSink, workingDir);
        TaskId taskId = context.getTaskId();
        String cookieNameSuffix = "Job" + taskId.getJobId().value() + "Task" + taskId.value();
        taskProcessTreeKiller = CookieBasedProcessTreeKiller.createProcessChildrenKiller(cookieNameSuffix, processBuilder.environment());
        process = processBuilder.start();
        processStreamsReader = new ProcessStreamsReader(taskId.toString(), process, outputSink, errorSink);
        int exitCode = process.waitFor();
        if (exitCode != 0) {
            try {
                Object error = deserializeTaskResult(serializedContext);
                if (error instanceof TaskContext) {
                    return createTaskResult(context, new IOException("Forked JVM process returned with exit code " + exitCode + ", see task logs for more information"));
                } else {
                    Throwable exception = (Throwable) error;
                    return createTaskResult(context, exception);
                }
            } catch (Throwable cannotDeserializeResult) {
                return createTaskResult(context, cannotDeserializeResult);
            }
        }
        return (TaskResultImpl) deserializeTaskResult(serializedContext);
    } catch (Throwable throwable) {
        return createTaskResult(context, throwable);
    } finally {
        FileUtils.deleteQuietly(serializedContext);
        if (process != null) {
            process.destroy();
        }
        if (taskProcessTreeKiller != null) {
            taskProcessTreeKiller.kill();
        }
        if (processStreamsReader != null) {
            processStreamsReader.close();
        }
    }
}
Also used : TaskId(org.ow2.proactive.scheduler.common.task.TaskId) TaskContext(org.ow2.proactive.scheduler.task.context.TaskContext) TaskResultImpl(org.ow2.proactive.scheduler.task.TaskResultImpl) IOException(java.io.IOException) OSProcessBuilder(org.objectweb.proactive.extensions.processbuilder.OSProcessBuilder) ProcessStreamsReader(org.ow2.proactive.scheduler.task.utils.ProcessStreamsReader) CookieBasedProcessTreeKiller(org.ow2.proactive.utils.CookieBasedProcessTreeKiller) File(java.io.File)

Aggregations

ScriptExecutableContainer (org.ow2.proactive.scheduler.task.containers.ScriptExecutableContainer)52 Test (org.junit.Test)51 TaskContext (org.ow2.proactive.scheduler.task.context.TaskContext)51 NodeDataSpacesURIs (org.ow2.proactive.scheduler.task.context.NodeDataSpacesURIs)43 SimpleScript (org.ow2.proactive.scripting.SimpleScript)40 TaskScript (org.ow2.proactive.scripting.TaskScript)40 TaskLauncherInitializer (org.ow2.proactive.scheduler.task.TaskLauncherInitializer)30 InProcessTaskExecutor (org.ow2.proactive.scheduler.task.executors.InProcessTaskExecutor)20 ForkEnvironment (org.ow2.proactive.scheduler.common.task.ForkEnvironment)17 Serializable (java.io.Serializable)16 TaskResultImpl (org.ow2.proactive.scheduler.task.TaskResultImpl)14 ScriptHandler (org.ow2.proactive.scripting.ScriptHandler)13 VariablesMap (org.ow2.proactive.scheduler.task.utils.VariablesMap)12 JobIdImpl (org.ow2.proactive.scheduler.job.JobIdImpl)10 HashMap (java.util.HashMap)9 TestTaskOutput (org.ow2.proactive.scheduler.task.TestTaskOutput)9 ForkedTaskExecutor (org.ow2.proactive.scheduler.task.executors.ForkedTaskExecutor)9 File (java.io.File)7 Decrypter (org.ow2.proactive.scheduler.task.utils.Decrypter)6 TaskResult (org.ow2.proactive.scheduler.common.task.TaskResult)5