Exception {
long sleepTime = 500;
long jobidDelayTime = 1000;
aggregateWarning = "true".equalsIgnoreCase(pc.getProperties().getProperty("aggregate.warning"));
MROperPlan mrp = compile(php, pc);
PigStats stats = new PigStats();
stats.setMROperatorPlan(mrp);
stats.setExecType(pc.getExecType());
stats.setPhysicalPlan(php);
ExecutionEngine exe = pc.getExecutionEngine();
ConfigurationValidator.validatePigProperties(exe.getConfiguration());
Configuration conf = ConfigurationUtil.toConfiguration(exe.getConfiguration());
JobClient jobClient = ((HExecutionEngine)exe).getJobClient();
JobControlCompiler jcc = new JobControlCompiler(pc, conf);
List<Job> failedJobs = new LinkedList<Job>();
List<Job> completeFailedJobsInThisRun = new LinkedList<Job>();
List<Job> succJobs = new LinkedList<Job>();
JobControl jc;
int totalMRJobs = mrp.size();
int numMRJobsCompl = 0;
double lastProg = -1;
//create the exception handler for the job control thread
//and register the handler with the job control thread
JobControlThreadExceptionHandler jctExceptionHandler = new JobControlThreadExceptionHandler();
while((jc = jcc.compile(mrp, grpName)) != null) {
List<Job> waitingJobs = jc.getWaitingJobs();
completeFailedJobsInThisRun.clear();
Thread jcThread = new Thread(jc);
jcThread.setUncaughtExceptionHandler(jctExceptionHandler);
jcThread.start();
Thread.sleep(jobidDelayTime);
String jobTrackerAdd;
String port;
try{
for (Job job : waitingJobs){
JobConf jConf = job.getJobConf();
port = jConf.get("mapred.job.tracker.http.address");
port = port.substring(port.indexOf(":"));
jobTrackerAdd = jConf.get(HExecutionEngine.JOB_TRACKER_LOCATION);
jobTrackerAdd = jobTrackerAdd.substring(0,jobTrackerAdd.indexOf(":"));
if (job.getAssignedJobID()!=null)
{
log.info("Submitting job: "+job.getAssignedJobID()+" to execution engine.");
log.info("More information at: http://"+ jobTrackerAdd+port+
"/jobdetails.jsp?jobid="+job.getAssignedJobID());
log.info("To kill this job, use: kill "+job.getAssignedJobID());
}
else
log.info("Cannot get jobid for this job");
}
}
catch(Exception e){
/* This is extra information Pig is providing to user.
If exception occurs here, job may still complete successfully.
So, pig shouldn't die or even give confusing message to the user.
So we just log information and move on. */
log.info("Cannot get jobid for this job");
}
while(!jc.allFinished()){
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {}
double prog = (numMRJobsCompl+calculateProgress(jc, jobClient))/totalMRJobs;
if(prog>=(lastProg+0.01)){
int perCom = (int)(prog * 100);
if(perCom!=100)
log.info( perCom + "% complete");
}
lastProg = prog;
}
//check for the jobControlException first
//if the job controller fails before launching the jobs then there are
//no jobs to check for failure
if(jobControlException != null) {
if(jobControlException instanceof PigException) {
if(jobControlExceptionStackTrace != null) {
LogUtils.writeLog("Error message from job controller", jobControlExceptionStackTrace,
pc.getProperties().getProperty("pig.logfile"),
log);
}
throw jobControlException;
} else {
int errCode = 2117;
String msg = "Unexpected error when launching map reduce job.";
throw new ExecException(msg, errCode, PigException.BUG, jobControlException);
}
}
if (!jc.getFailedJobs().isEmpty() )
{
if ("true".equalsIgnoreCase(
pc.getProperties().getProperty("stop.on.failure","false"))) {
int errCode = 6017;
StringBuilder msg = new StringBuilder();
for (int i=0;i<jc.getFailedJobs().size();i++) {
Job j = jc.getFailedJobs().get(i);
msg.append(getFirstLineFromMessage(j.getMessage()));
if (i!=jc.getFailedJobs().size()-1)
msg.append("\n");
}
throw new ExecException(msg.toString(),
errCode, PigException.REMOTE_ENVIRONMENT);
}
// If we only have one store and that job fail, then we sure that the job completely fail, and we shall stop dependent jobs
for (Job job : jc.getFailedJobs())
{
List<POStore> sts = jcc.getStores(job);
if (sts.size()==1)
completeFailedJobsInThisRun.add(job);
}
failedJobs.addAll(jc.getFailedJobs());
}
int removedMROp = jcc.updateMROpPlan(completeFailedJobsInThisRun);
numMRJobsCompl += removedMROp;
List<Job> jobs = jc.getSuccessfulJobs();
jcc.moveResults(jobs);
succJobs.addAll(jobs);
stats.setJobClient(jobClient);
stats.setJobControl(jc);
stats.accumulateStats();
jc.stop();
}
log.info( "100% complete");
boolean failed = false;
int finalStores = 0;
// Look to see if any jobs failed. If so, we need to report that.
if (failedJobs != null && failedJobs.size() > 0) {
log.error(failedJobs.size()+" map reduce job(s) failed!");
Exception backendException = null;
for (Job fj : failedJobs) {
try {
getStats(fj, jobClient, true, pc);
} catch (Exception e) {
backendException = e;
}
List<POStore> sts = jcc.getStores(fj);
for (POStore st: sts) {
if (!st.isTmpStore()) {
finalStores++;
log.error("Failed to produce result in: \""+st.getSFile().getFileName()+"\"");
}
failedStores.add(st.getSFile());
failureMap.put(st.getSFile(), backendException);
FileLocalizer.registerDeleteOnFail(st.getSFile().getFileName(), pc);
//log.error("Failed to produce result in: \""+st.getSFile().getFileName()+"\"");
}
}
failed = true;
}
Map<Enum, Long> warningAggMap = new HashMap<Enum, Long>();
if(succJobs!=null) {
for(Job job : succJobs){
List<POStore> sts = jcc.getStores(job);
for (POStore st: sts) {
if (!st.isTmpStore()) {
succeededStores.add(st.getSFile());
finalStores++;
log.info("Successfully stored result in: \""+st.getSFile().getFileName()+"\"");
}
else
log.debug("Successfully stored result in: \""+st.getSFile().getFileName()+"\"");
}
getStats(job,jobClient, false, pc);
if(aggregateWarning) {
computeWarningAggregate(job, jobClient, warningAggMap);
}
}
}
if(aggregateWarning) {
CompilationMessageCollector.logAggregate(warningAggMap, MessageType.Warning, log) ;
}
// Report records and bytes written. Only do this in the single store case. Multi-store
// scripts mess up the stats reporting from hadoop.
List<String> rji = stats.getRootJobIDs();
if (rji != null && rji.size() == 1 && finalStores == 1) {
if(stats.getRecordsWritten()==-1) {
log.info("Records written : Unable to determine number of records written");
} else {
log.info("Records written : " + stats.getRecordsWritten());
}
if(stats.getBytesWritten()==-1) {
log.info("Bytes written : Unable to determine number of bytes written");
} else {
log.info("Bytes written : " + stats.getBytesWritten());
}
}
if (!failed) {
log.info("Success!");