1
votes

I have a batch job which has to be repeated for a list of items. So I have a "parent" job which uses a batchlet step to load the list and start a child job for each id in the list. Each child job is launched using JobOperator and param using Properties class and this works fine as expected.

I have to retrieve the batch status and wait for the child job to be completed, in order to iterate through the list. I'm trying to get the batch status or exit status using the JobExecution class, however the JobExecution is not retrieving the batch status for the child job.

Instead, I always see the batch status of STARTED, even after the child job completes.

My code looks like:

for (int i = 1; i <= rsList; i++) {
            long execId = jobOperator.start("gah-history-chunk-archive-job",jobParamProperties);
            JobInstance jobInstance = jobOperator.getJobInstance(execId);
            JobExecution jobExecution = jobOperator.getJobExecution(execId);
            logger.info("Instance id: "+jobInstance.getInstanceId());
            while(!jobExecution.getBatchStatus().toString().equals("COMPLETED") || !jobExecution.getBatchStatus().toString().equals("FAILED")) {
                //Both batch status and exit status giving the status of this batchlet, not giving the status of gah-history-chunk-archive-job
logger.info("Batch status is: "+jobExecution.getBatchStatus() +" Thread is sleeping for 5 seconds");
                logger.info("Exit status:"+jobExecution.getExitStatus());

                Thread.sleep(300);
            }
        }

I want to know, how to retrieve batch or exit status of the child job launched from the batchlet. Why do I continue to see a BatchStatus of STARTED?

3
jobExecution.getBatchStatus() always comes as STARTED even though the child job has completed. - user3540722
which implementation product are you using, and in what server environment? Nested batch job execution is not common and so it depends a lot on each implementation. - cheng
If you are running the same logic on each "child" you should take a good look at "partitions". With a partitioned step, the waiting for the children and the aggregating of the child statuses into the parent job/step status is handled for you by the batch container. This seems like a use case which would map well to this function. - Scott Kurz
@user3540722 did my answer address the core of your question? I'm thinking of either editing your question a bit and/or posting a new, separate question to explain the point about polling JobExecution vs. BatchStatus. - Scott Kurz
Seeing my answer was accepted, I rephrased the question and removed less helpful details. Thank you @user3540722 for the question. I think this rework will make it even more helpful to others. - Scott Kurz

3 Answers

1
votes

To "poll" the status of a JobExecution you should obtain a new instance from the JobOperator each time you check its status. So get the JobExecution inside the while-loop, NOT outside.

So it should be more like, for example:

do {
  Thread.sleep(300);

  // log or whatever

  BatchStatus status = jobOperator.getJobExecution(execId).getBatchStatus();

}  while(status != BatchStatus.COMPLETED && status != BatchStatus.FAILED) ;

This is a bit tricky because the behavior here is not standardized by the specification.
Because the spec allows for a diversity of job repository implementations (e.g. database, simple in-memory map, other, ...), it doesn't require a specific behavior for a "cached" JobExecution, and you may find that it "works" some of the time with your original code.

I don't think that what you are actually seeing is the "parent" object instance being returned; I suspect you may just be getting confused by not seeing what you expected.

In any case, to have your code be more portable, obtain the JobExecution with each status check.

0
votes

JobExecution points to the parent job, even though its been setup with the child job execution id. Not sure why batch behaves in this way.

JobExecution jobExecution = jobOperator.getJobExecution(execId);
jobExecution.getBatchStatus(); //Parent job status

But If we go with the BatchRuntime class, we can get the corresponding job, batch status. This helps me to get the child job status and can loop to the next batch launch.

//Returns the child job status as expected
BatchRuntime.getJobOperator().getJobExecution(execId).getBatchStatus();

0
votes

I would recommend to poll the Exitstatus of the job instead of the BatchStatus itself:

for (int i = 1; i <= rsList; i++) {
    long execId = jobOperator.start("gah-history-chunk-archive-job",jobParamProperties);
    JobInstance jobInstance = jobOperator.getJobInstance(execId);
    JobExecution jobExecution = jobOperator.getJobExecution(execId);
    logger.info("Instance id: "+jobInstance.getInstanceId());
    while(jobExecution.getExitStatus() == null) {
        //do your logging etc.   
        Thread.sleep(300);
    }
}