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();
}
}
}
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);
}
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;
}
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;
}
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();
}
}
}
Aggregations