|
[
Permlink
| « Hide
]
Dave Syer added a comment - 30/Dec/07 01:51 PM
The best way to do that is to set up the chain as a series of steps and then check for the business condition that would terminate the job using a RepeatInterceptor at the step operations level. Can you suggest some scenarios where this will not work?
Dave,
may be I am missing something here. Do you mean that I write a container job that will have all the jobs as steps? If yes then that would not satisfy the requirements. I will try to give some scenarios to make the requirement clear. Scenario1 JobB depends on successful completion of JobA JobC depends on successful completion of JobA. Both JobB and JobC are scheduled to run at the same time. Scenario2 JobF depends on successful completion of JobD and JobE JobG depends on successul completion of JobD only. Scenario3 Successful completion of JobH triggers JobI Failure of JobH triggers JobJ I am thinking of some solution as follows: Scenario1 Both JobB and JobC has following property. <property name="predecessors"> <bean class="batch.core.JobPredecessor"> <property name="jobName" value="JobA" /> <property name="exitStatus" value="COMPLETED" /> </bean> </property> Scenario2 JobF has following predecessors <property name="predecessors"> <bean class="batch.core.JobPredecessor"> <property name="jobName" value="JobD" /> <property name="exitStatus" value="COMPLETED" /> </bean> <bean class="batch.core.JobPredecessor"> <property name="jobName" value="JobE" /> <property name="exitStatus" value="COMPLETED" /> </bean> </property> while JobD has only JobD as predecessor. Scenario3 JobH has following as successors <property name="successors"> <bean class="batch.core.JobSuccessor"> <property name="jobName" value="JobI" /> <property name="exitStatus" value="COMPLETED" /> </bean> <bean class="batch.core.JobSuccessor"> <property name="jobName" value="JobJ" /> <property name="exitStatus" value="FAILED" /> </bean> </property> Initially we were planning to implement this in before and after methods of JobListeners but we did not find a way to gracefully return (without creating an entry for job) from the before method so we decided to put it in quartz job listener. Thanks, Rajiv I think you mean JobExecutionListener? I think it might be appropriate to put a test in the JobExecutor to check if a listener has vetoed the execution of a job, by setting its status / end time etc. Would that help?
If by "without creating an entry for job" you mean "without creating a JobExecution instance and persisting it" I don't think we can support that, for two reasons. 1) there has to be an audit of every attempted job execution. 2) to prevent concurrent execution of the same job the creation of the JobExecution and saving it in the database has to be atomic (transactional and blocking). I was thinking at a lower level of having a listener to the step (via RepeatInterceptor) which can definitely already veto the further execution of a step. I am more and more convinced that the right level to specify dependencies is between steps (not jobs). The main reason for this conclusion is that with steps there is already an "aggregate" concept which links the executions together (the JobExecution). If we create dependencies between jobs in the framework then we'll have to track the execution of the linked set of jobs through another aggregate, which seems pointless, since JobExecution already does a perfectly good job.
If we operated at the job level (with a new aggregate called JobExecutionPlan, perhaps), then each job would have to be seeded with its own parameters. Maybe this could be an argument in favour of a new aggregate. But parameters for dependent executions are normally context dependent (it depends on how you got there), e.g. the input file for step 2 is created by step 1, and so I think the fact that each job has its own parameters is not a huge benefit, where ExecutionContext can already be used to supply the necessary parameters. If there are no new insights in 2.0.0.M1 I think we should close this issue, and concentrate on the step dependencies (which are already provided by StepExecutionMessageHandler). |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||