public String getJobId() { return this.jobContext.getJobId(); }
/** * Submit a job to run. */ private void submitJobToHelix(JobConfig.Builder jobConfigBuilder) throws Exception { HelixUtils.submitJobToWorkFlow(jobConfigBuilder, this.helixWorkFlowName, this.jobContext.getJobId(), this.helixTaskDriver, this.helixManager, this.workFlowExpiryTimeSeconds); }
@Override public String toString() { return Objects.toStringHelper(JobContext.class.getSimpleName()).add("jobName", getJobName()) .add("jobId", getJobId()).add("jobState", getJobState()).toString(); } }
@Override protected void executeCancellation() { try { if (this.hadoopJobSubmitted && !this.job.isComplete()) { LOG.info("Killing the Hadoop MR job for job " + this.jobContext.getJobId()); this.job.killJob(); // Collect final task states. this.taskStateCollectorService.stopAsync().awaitTerminated(); } } catch (IllegalStateException ise) { LOG.error("The Hadoop MR job has not started for job " + this.jobContext.getJobId()); } catch (IOException ioe) { LOG.error("Failed to kill the Hadoop MR job for job " + this.jobContext.getJobId()); } }
private void waitForJobCompletion() throws InterruptedException { boolean timeoutEnabled = Boolean.parseBoolean(this.jobProps.getProperty( GobblinClusterConfigurationKeys.HELIX_JOB_TIMEOUT_ENABLED_KEY, GobblinClusterConfigurationKeys.DEFAULT_HELIX_JOB_TIMEOUT_ENABLED)); long timeoutInSeconds = Long.parseLong(this.jobProps.getProperty( GobblinClusterConfigurationKeys.HELIX_JOB_TIMEOUT_SECONDS, GobblinClusterConfigurationKeys.DEFAULT_HELIX_JOB_TIMEOUT_SECONDS)); try { HelixUtils.waitJobCompletion( this.helixManager, this.helixWorkFlowName, this.jobContext.getJobId(), timeoutEnabled? Optional.of(timeoutInSeconds) : Optional.empty()); } catch (TimeoutException te) { HelixUtils.handleJobTimeout(helixWorkFlowName, jobContext.getJobId(), helixManager, this, this.jobListener); } }
/** * Unlock a completed or failed job. */ private void unlockJob() { if (this.jobLockOptional.isPresent()) { try { // Unlock so the next run of the same job can proceed this.jobLockOptional.get().unlock(); } catch (JobLockException ioe) { LOG.error(String.format("Failed to unlock for job %s: %s", this.jobContext.getJobId(), ioe), ioe); } finally { try { this.jobLockOptional.get().close(); } catch (IOException e) { LOG.error(String.format("Failed to close job lock for job %s: %s", this.jobContext.getJobId(), e), e); } finally { this.jobLockOptional = Optional.absent(); } } } }
void checkForUnpublishedWUHandling(String datasetUrn, JobState.DatasetState datasetState, Class<? extends DataPublisher> dataPublisherClass, Closer closer) throws ReflectiveOperationException, IOException { if (UnpublishedHandling.class.isAssignableFrom(dataPublisherClass)) { // pass in jobstate to retrieve properties DataPublisher publisher = closer.register(DataPublisher.getInstance(dataPublisherClass, this.jobContext.getJobState())); log.info(String.format("Calling publisher to handle unpublished work units for dataset %s of job %s.", datasetUrn, this.jobContext.getJobId())); ((UnpublishedHandling) publisher).handleUnpublishedWorkUnits(datasetState.getTaskStatesAsWorkUnitStates()); } }
/** * Add a single {@link WorkUnit} (flattened). */ private void addWorkUnit(WorkUnit workUnit, ParallelRunner stateSerDeRunner, Map<String, TaskConfig> taskConfigMap) throws IOException { String workUnitFilePath = persistWorkUnit( new Path(this.inputWorkUnitDir, this.jobContext.getJobId()), workUnit, stateSerDeRunner); Map<String, String> rawConfigMap = Maps.newHashMap(); rawConfigMap.put(GobblinClusterConfigurationKeys.WORK_UNIT_FILE_PATH, workUnitFilePath); rawConfigMap.put(ConfigurationKeys.JOB_NAME_KEY, this.jobContext.getJobName()); rawConfigMap.put(ConfigurationKeys.JOB_ID_KEY, this.jobContext.getJobId()); rawConfigMap.put(ConfigurationKeys.TASK_ID_KEY, workUnit.getId()); rawConfigMap.put(GobblinClusterConfigurationKeys.TASK_SUCCESS_OPTIONAL_KEY, "true"); taskConfigMap.put(workUnit.getId(), TaskConfig.Builder.from(rawConfigMap)); }
/** * Try acquiring the job lock and return whether the lock is successfully locked. * * @param properties the job properties */ private boolean tryLockJob(Properties properties) { try { if (Boolean.valueOf(properties.getProperty(ConfigurationKeys.JOB_LOCK_ENABLED_KEY, Boolean.TRUE.toString()))) { this.jobLockOptional = Optional.of(getJobLock(properties, new JobLockEventListener() { @Override public void onLost() { executeCancellation(); } })); } return !this.jobLockOptional.isPresent() || this.jobLockOptional.get().tryLock(); } catch (JobLockException ioe) { LOG.error(String.format("Failed to acquire job lock for job %s: %s", this.jobContext.getJobId(), ioe), ioe); return false; } }
/** * Delete persisted {@link WorkUnit}s and {@link JobState} upon job completion. */ private void cleanupWorkingDirectory() throws IOException { LOGGER.info("Deleting persisted work units for job " + this.jobContext.getJobId()); stateStores.getWuStateStore().delete(this.jobContext.getJobId()); // delete the directory that stores the task state files stateStores.getTaskStateStore().delete(outputTaskStateDir.getName()); LOGGER.info("Deleting job state file for job " + this.jobContext.getJobId()); if (this.stateStores.haveJobStateStore()) { this.stateStores.getJobStateStore().delete(this.jobContext.getJobId()); } else { Path jobStateFilePath = GobblinClusterUtils.getJobStateFilePath(false, this.appWorkDir, this.jobContext.getJobId()); this.fs.delete(jobStateFilePath, false); } }
@Override public void run() { synchronized (AbstractJobLauncher.this.cancellationRequest) { try { while (!AbstractJobLauncher.this.cancellationRequested) { // Wait for a cancellation request to arrive AbstractJobLauncher.this.cancellationRequest.wait(); } LOG.info("Cancellation has been requested for job " + AbstractJobLauncher.this.jobContext.getJobId()); executeCancellation(); LOG.info("Cancellation has been executed for job " + AbstractJobLauncher.this.jobContext.getJobId()); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); } } synchronized (AbstractJobLauncher.this.cancellationExecution) { AbstractJobLauncher.this.cancellationExecuted = true; AbstractJobLauncher.this.jobContext.getJobState().setState(JobState.RunningState.CANCELLED); // Notify that the cancellation has been executed AbstractJobLauncher.this.cancellationExecution.notifyAll(); } } });
/** * Prepare the flattened {@link WorkUnit}s for execution by populating the job and task IDs. */ private WorkUnitStream prepareWorkUnits(WorkUnitStream workUnits, JobState jobState) { return workUnits.transform(new WorkUnitPreparator(this.jobContext.getJobId())); }
public void launchJob(@Nullable JobListener jobListener) throws JobException { this.jobListener = jobListener; boolean isLaunched = false; this.runningMap.putIfAbsent(this.jobContext.getJobName(), false); try { if (this.runningMap.replace(this.jobContext.getJobName(), false, true)) { LOGGER.info ("Job {} will be executed, add into running map.", this.jobContext.getJobId()); isLaunched = true; super.launchJob(jobListener); } else { LOGGER.warn ("Job {} will not be executed because other jobs are still running.", this.jobContext.getJobId()); } } finally { if (isLaunched) { if (this.runningMap.replace(this.jobContext.getJobName(), true, false)) { LOGGER.info ("Job {} is done, remove from running map.", this.jobContext.getJobId()); } else { throw new IllegalStateException("A launched job should have running state equal to true in the running map."); } } } }
@Override public void close() throws IOException { try { if (this.hadoopJobSubmitted && !this.job.isComplete()) { LOG.info("Killing the Hadoop MR job for job " + this.jobContext.getJobId()); this.job.killJob(); } } finally { try { cleanUpWorkingDirectory(); } finally { super.close(); fs.close(); } } }
/** * FIXME this method is provided for backwards compatibility in the LocalJobLauncher since it does * not access the task state store. This should be addressed as all task executions should be * updating the task state. */ public static GobblinMultiTaskAttempt runWorkUnits(JobContext jobContext, Iterator<WorkUnit> workUnits, TaskStateTracker taskStateTracker, TaskExecutor taskExecutor, CommitPolicy multiTaskAttemptCommitPolicy) throws IOException, InterruptedException { GobblinMultiTaskAttempt multiTaskAttempt = new GobblinMultiTaskAttempt(workUnits, jobContext.getJobId(), jobContext.getJobState(), taskStateTracker, taskExecutor, Optional.<String>absent(), Optional.<StateStore<TaskState>>absent(), jobContext.getJobBroker()); multiTaskAttempt.runAndOptionallyCommitTaskAttempt(multiTaskAttemptCommitPolicy); return multiTaskAttempt; }
/** * Prepare the job input. * @throws IOException */ private void prepareJobInput(List<WorkUnit> workUnits) throws IOException { Closer closer = Closer.create(); try { ParallelRunner parallelRunner = closer.register(new ParallelRunner(this.parallelRunnerThreads, this.fs)); int multiTaskIdSequence = 0; // Serialize each work unit into a file named after the task ID for (WorkUnit workUnit : workUnits) { String workUnitFileName; if (workUnit instanceof MultiWorkUnit) { workUnitFileName = JobLauncherUtils.newMultiTaskId(this.jobContext.getJobId(), multiTaskIdSequence++) + MULTI_WORK_UNIT_FILE_EXTENSION; } else { workUnitFileName = workUnit.getProp(ConfigurationKeys.TASK_ID_KEY) + WORK_UNIT_FILE_EXTENSION; } Path workUnitFile = new Path(this.jobInputPath, workUnitFileName); LOG.debug("Writing work unit file " + workUnitFileName); parallelRunner.serializeToFile(workUnit, workUnitFile); // Append the work unit file path to the job input file } } catch (Throwable t) { throw closer.rethrow(t); } finally { closer.close(); } }
this.inputWorkUnitDir = new Path(appWorkDir, GobblinClusterConfigurationKeys.INPUT_WORK_UNIT_DIR_NAME); this.outputTaskStateDir = new Path(this.appWorkDir, GobblinClusterConfigurationKeys.OUTPUT_TASK_STATE_DIR_NAME + Path.SEPARATOR + this.jobContext.getJobId()); this.helixWorkFlowName = this.jobContext.getJobId(); this.jobContext.getJobState().setJobLauncherType(LauncherTypeEnum.CLUSTER);
@Override protected void runWorkUnitStream(WorkUnitStream workUnitStream) throws Exception { String jobId = this.jobContext.getJobId(); final JobState jobState = this.jobContext.getJobState();
@Override public void close() throws IOException { try { this.cancellationExecutor.shutdownNow(); try { this.jobContext.getSource().shutdown(this.jobContext.getJobState()); } finally { if (GobblinMetrics.isEnabled(this.jobProps)) { GobblinMetricsRegistry.getInstance().remove(this.jobContext.getJobId()); } } } finally { unlockJob(); } }
when(jobContext.getStagingDirProvided()).thenReturn(false); when(jobContext.getOutputDirProvided()).thenReturn(false); when(jobContext.getJobId()).thenReturn(currentJobPath.getName().toString());