Run State & Recovery
If SDLB is started with --state-path, it writes a state file for every run.
The state file records what each Action did, and it is what enables SDLB to recover a failed run on the next start.
An application name (-n / --name) is mandatory when a state path is set.
Directory layout
<state-path>/
├── current/
│ └── <appName>.<runId>.<attemptId>.json
├── succeeded/
│ └── <appName>.<runId>.<attemptId>.json
└── index.json
current/holds the state file of the run in progress, and of runs which did not finish successfully.succeeded/holds the state files of finished runs. A run is moved here as soon as it succeeds, together with the state files of its earlier, failed attempts.index.jsonis an optional one-line-per-run index, see below.
The <runId> is incremented by one for every new run. The <attemptId> is 1 for a normal run and incremented by one
for every recovery of the same run. Note that . separates the file name parts, so the application name must not
contain a dot or whitespace.
When is a run recovered?
On startup SDLB reads the state file with the highest (runId, attemptId), from either directory, and decides:
- If every Action of that run is
SUCCEEDED,SKIPPEDorSTREAMING, and the state is final, the run is considered finished. SDLB starts a new run withrunId + 1, carrying over the incremental state of the DataObjects (dataObjectsState). - Otherwise the run is to be recovered: If it is in
succeeded/directory, SDLB issues logs warning and creates an new run. If it is incurrent/directory, SDLB starts a new attempt with the samerunIdandattemptId + 1. Actions that areSUCCEEDEDorSKIPPEDare not executed again — their results and metrics are carried over into the new attempt. Everything else (FAILED,CANCELLED,PENDING, …) is executed again.
Because the state file of an attempt always contains the carried-over information of the previous attempts, the latest state file of a run is a complete picture of the whole run.
When recovering, the command line parameters must match the ones of the run being recovered — otherwise SDLB aborts with an assertion error rather than silently continuing a run with a different configuration.
Accepting a failed run
Sometimes a failed run must not be retried, e.g. because the failure was analysed and accepted, or because the
missing data will never arrive. Instead of editing the state file by hand, move it from current/ to succeeded/:
mv <state-path>/current/<appName>.<runId>.<attemptId>.json <state-path>/succeeded/
A state file in succeeded/ is accepted: on the next start SDLB does not recover it, but starts a new run with
runId + 1. The incremental DataObject state of the accepted run is still carried over. SDLB logs a warning naming
the Actions that never completed, so it stays visible in the log why they were not retried:
WARN run runId=5 attemptId=2 has unfinished actions (a2, a3), but its state file is accepted
-> not recovering it and starting a new run instead
Index file
Setting the SDL parameter hadoopFileStateStoreIndexAppend = true makes SDLB append one compact JSON line per
finished run to <state-path>/index.json, containing run id, attempt id, feed selector, start/end times, final
state, the state and output DataObjects per Action, the SDLB and application versions, and the relative path of the
state file. This is used by the local UI, see Metadata.
State file format version
State files carry a runStateFormatVersion. SDLB migrates older state files to the current format when reading them,
so an upgrade does not invalidate a pending recovery. Reading a state file written by a newer SDLB version fails
with an explicit error. Existing state files can also be migrated in place with the StateMigrator tool
(io.smartdatalake.meta.state.StateMigrator -s <state-path>).