/* * Copyright 2015-2016 OpenCB * * 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 org.opencb.opencga.catalog.monitor.executors; import org.opencb.commons.exec.Command; import org.opencb.commons.exec.RunnableProcess; import org.opencb.opencga.catalog.models.Job; import org.slf4j.LoggerFactory; import java.io.DataOutputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; /** * Created by pfurio on 22/08/16. */ public class LocalExecutor extends AbstractExecutor { private static int threadInitNumber; public LocalExecutor() { logger = LoggerFactory.getLogger(LocalExecutor.class); } @Override public void execute(Job job) throws Exception { Runnable runnable = () -> { ExecutorConfig executorConfig = null; try { executorConfig = getExecutorConfig(job); logger.info("Ready to run {}", job.getCommandLine()); Command com = new Command(job.getCommandLine()); DataOutputStream dataOutputStream = new DataOutputStream(new FileOutputStream(executorConfig.getStdout())); com.setOutputOutputStream(dataOutputStream); dataOutputStream = new DataOutputStream(new FileOutputStream(executorConfig.getStderr())); com.setErrorOutputStream(dataOutputStream); final long jobId = job.getId(); Thread hook = new Thread(() -> { logger.info("Running ShutdownHook. Job {id: " + jobId + "} has being aborted."); com.setStatus(RunnableProcess.Status.KILLED); com.setExitValue(-2); closeOutputStreams(com); }); logger.info("=========================================="); logger.info("Executing job {}({})", job.getName(), job.getId()); logger.debug("Executing commandLine {}", job.getCommandLine()); logger.info("=========================================="); System.err.println(); Runtime.getRuntime().addShutdownHook(hook); com.run(); Runtime.getRuntime().removeShutdownHook(hook); System.err.println(); logger.info("=========================================="); logger.info("Finished job {}({})", job.getName(), job.getId()); logger.info("=========================================="); closeOutputStreams(com); } catch (FileNotFoundException e) { logger.error("Could not create the output/error files", e); } finally { if (executorConfig != null) { Path outdir = Paths.get(executorConfig.getOutdir()); // The outdir folder may be removed by the IndexDaemon if (outdir.toFile().exists()) { String status = status(outdir, job); if (!status.equals(Job.JobStatus.DONE) && !status.equals(Job.JobStatus.READY) && !status.equals(Job.JobStatus.ERROR)) { logger.error("Job {} finished with status {}. Write {} with status {}", job.getId(), status, JOB_STATUS_FILE, Job.JobStatus.ERROR); try { Path jobStatusFile = outdir.resolve(JOB_STATUS_FILE); Job.JobStatus jobStatus = new Job.JobStatus(Job.JobStatus.ERROR, "Job finished with status " + status); objectMapper.writer().writeValue(jobStatusFile.toFile(), jobStatus); } catch (IOException e) { logger.error("Could not write the " + JOB_STATUS_FILE + " with status " + Job.JobStatus.ERROR, e); } } } } } }; Thread thread = new Thread(runnable, "LocalExecutor-" + nextThreadNum()); thread.start(); } private static synchronized int nextThreadNum() { return threadInitNumber++; } @Override protected String getStatus(Job job) { return Job.JobStatus.UNKNOWN; } @Override public boolean stop(Job job) throws Exception { return false; } @Override public boolean resume(Job job) throws Exception { return false; } @Override public boolean kill(Job job) throws Exception { return false; } @Override public boolean isExecutorAlive() { return false; } private void closeOutputStreams(Command com) { /** Close output streams **/ if (com.getOutputOutputStream() != null) { try { com.getOutputOutputStream().close(); } catch (IOException e) { logger.warn("Error closing OutputStream", e); } com.setOutputOutputStream(null); com.setOutput(null); } if (com.getErrorOutputStream() != null) { try { com.getErrorOutputStream().close(); } catch (IOException e) { logger.warn("Error closing OutputStream", e); } com.setErrorOutputStream(null); com.setError(null); } } }