Lemric BatchProcessing supports full restart semantics — a failed or stopped job can be re-launched from its last checkpoint.
- A
JobInstanceis identified by(jobName, hash(identifyingParameters)). - Re-running with the same identifying parameters finds the existing
JobInstance:
| Existing State | Behaviour |
|---|---|
COMPLETED |
JobInstanceAlreadyCompleteException is thrown |
STARTED |
JobExecutionAlreadyRunningException is thrown |
FAILED |
A new JobExecution is created — job resumes |
STOPPED |
A new JobExecution is created — job resumes |
ABANDONED |
JobRestartException is thrown |
- On restart each step checks for a previous
StepExecution:- If the step was
COMPLETED, it is skipped (unlessallowStartIfCompleteis set). - If the step was
FAILEDorSTOPPED, it re-executes with the persistedExecutionContext.
- If the step was
The ExecutionContext is persisted after every committed chunk. Readers and
writers implementing ItemStreamInterface store their cursor position:
public function open(ExecutionContext $ctx): void
{
// Restore from last checkpoint
$this->currentLine = $ctx->getInt('reader.current.line', 0);
}
public function update(ExecutionContext $ctx): void
{
// Save checkpoint
$ctx->put('reader.current.line', $this->currentLine);
}$job = $jobBuilderFactory->get('oneTimeJob')
->start($step)
->preventRestart(true)
->build();By default, completed steps are skipped on restart. To force re-execution:
$step = $stepBuilderFactory->get('alwaysRunStep')
->chunk(100, $reader, $processor, $writer)
->allowStartIfComplete(true)
->build();Request a graceful stop via the operator:
$operator->stop($executionId); // returns boolThe framework checks the interruption policy before each chunk. The job will
complete the current chunk, persist the context, and exit with STOPPED
status.
Mark a stopped/failed job as abandoned to permanently prevent restart:
$operator->abandon($executionId); // returns the updated JobExecutionWhen ext-pcntl is available, SignalHandler /
SignalJobInterruptionPolicy intercept SIGTERM and SIGINT signals and set
the job to STOPPING for a graceful shutdown.