[Feature][Zeta] Report non-terminal job states - #10133
Conversation
…e/job-state-event
|
Hi @zhangshenghang , PTAL when you have time. Thanks! |
chl-wxp
left a comment
There was a problem hiding this comment.
docs/zh/concept/event-listener.md, please modify this document as well.
…e/job-state-event
…e/job-state-event
|
Hi @dybyte, thanks for working on this. I reviewed the PR from a local branch against the current What This PR Solves
1. Code Change Review1.1 Core Logic AnalysisLocal review basis:
The important code changes are:
Before this PR, terminal events were emitted only in the terminal branch of case FAILED:
case CANCELED:
case SAVEPOINT_DONE:
case FINISHED:
stopJobStateProcess();
jobEndFuture.complete(new JobResult(jobStatus, errorBySubPlan.get()));
jobMaster
.getCoordinatorService()
.getEventProcessor()
.process(
new JobStateEvent(
jobImmutableInformation.getJobId(),
jobImmutableInformation.getJobConfig().getName(),
jobStatus));
return;After this PR, the event reporting is moved to a common helper called from the tail of case FAILED:
case CANCELED:
case SAVEPOINT_DONE:
case FINISHED:
stopJobStateProcess();
jobEndFuture.complete(new JobResult(jobStatus, errorBySubPlan.get()));
break;
default:
throw new IllegalArgumentException("Unknown Job State: " + jobStatus);
}
reportJobStateEvent(jobStatus);private void reportJobStateEvent(JobStatus jobStatus) {
try {
if (jobStatus.isEndState()
|| (this.engineConfig != null
&& this.engineConfig.isReportNonTerminalJobState())) {
jobMaster
.getCoordinatorService()
.getEventProcessor()
.process(
new JobStateEvent(
jobId,
jobImmutableInformation.getJobConfig().getName(),
jobStatus));
}
} catch (Exception e) {
log.warn("Failed to report job {} state event", jobId, e);
}
}Key findings:
Complete runtime flow: 1.2 Compatibility ImpactVerdict: compatible by default, but the opt-in behavior needs a correctness fix.
1.3 Performance / Side EffectsCPU, memory, and GC impact should be low because job state transitions are low frequency. Network traffic increases only when the option is enabled and an HTTP endpoint is configured. The main side effect is semantic rather than resource-related: the current duplicate 1.4 Error Handling and LogsThe new Issue 1: Non-terminal events are missed, out of order, and duplicated on the normal startup path
2. Code Quality2.1 StyleThe naming and config style are consistent with the surrounding code. The main quality concern is the location of the event emission: 2.2 TestsThe added test proves that some non-terminal events can be observed, but it misses the critical contract:
I did not run the PR locally per the requested review mode; this is based on local source analysis and the GitHub check results. 2.3 DocsBoth English and Chinese docs were updated consistently:
However, the current implementation does not satisfy the documented 3. Architecture3.1 EleganceThe feature direction is good and the default-off config is the right compatibility choice. The implementation is not yet precise because it hooks into state processing instead of state transition persistence. 3.2 MaintainabilityMoving event emission to the successful 3.3 ExtensibilityIf we later add transition reasons, duration, or pipeline-level state events, we need a clear “state changed” publication point. The current 3.4 Historical CompatibilityExisting users are compatible because the option defaults to 4. Issue Summary
5. Merge DecisionConclusion: can merge after fixes
Overall, I like the feature goal and the compatibility shape. Once the event emission is tied to successful state transitions and the test asserts the real sequence, this should be a solid improvement. |
…e/job-state-event
|
Hi @DanielLeens , I have addressed the issues. |
Retrigger CI
ea0f1d3 to
b383356
Compare
DanielLeens
left a comment
There was a problem hiding this comment.
Thanks for the update and for addressing the earlier concern. I re-reviewed the latest head from the full diff and retraced the actual Zeta job-state path again instead of only checking the changed lines.
What this PR solves
- User pain: without this option, external systems only see terminal
JobStateEvents and cannot reliably reconstruct the full job lifecycle. - Fix approach: the PR adds
event-report-http.report-non-terminal-job-state, keeps it default-off, and reports non-terminal job states when the option is enabled. - One-line summary: this is a useful, compatibility-safe observability improvement, and the previous event-ordering blocker is fixed on the current head.
Runtime path I rechecked
Job submission
-> CoordinatorService.submitJob(...) [CoordinatorService.java:619-691]
-> updateJobState(PENDING) [CoordinatorService.java:679]
-> updateStateInfo(PENDING)
-> reportJobStateEvent(PENDING)
-> stateProcess() returns because isRunning=false
Job start
-> JobMaster.run()
-> PhysicalPlan.startJob() [PhysicalPlan.java:349-353]
-> isRunning=true
-> updateJobState(SCHEDULED)
-> persist SCHEDULED
-> report SCHEDULED
-> stateProcess()
-> start pipelines
-> updateJobState(RUNNING)
-> persist RUNNING
-> report RUNNING
-> stateProcess() breaks on RUNNING
-> startJob() tail calls stateProcess() again
-> current state already RUNNING, so no duplicate event is emitted
Terminal / failing path
-> pipeline end callback [PhysicalPlan.java:154-188]
-> updateJobState(FAILED/CANCELED/SAVEPOINT_DONE/FINISHED)
-> persist target state
-> report that exact state once
-> stateProcess() completes stop / future completion / cancel flow
Key findings
- The earlier blocker I raised is fixed on the latest head.
reportJobStateEvent(...)is now called fromupdateJobState(...)right after the target state is persisted (PhysicalPlan.java:318-323) instead of from the tail ofstateProcess(). - Because of that, the normal path now follows the persisted transition order
PENDING -> SCHEDULED -> RUNNING -> terminal, instead of the olderRUNNING -> SCHEDULED -> RUNNINGsequence. - The compatibility shape is still good: the new option defaults to
false, so existing users keep the terminal-only behavior unless they opt in. - I do not see a source-level blocker on the current head.
One non-blocking follow-up
JobStateEventTest.java:154-159andJobStateEventTest.java:223-239are much better than before, but they still do not assert the full exact sequence as a strict contract. As a follow-up, I would strengthen the assertions to explicitly check:- success path:
PENDING -> SCHEDULED -> RUNNING -> FINISHED - failure path:
PENDING -> SCHEDULED -> RUNNING -> FAILING -> FAILED - and that
RUNNINGis emitted exactly once
- success path:
CI note
- The current GitHub
Buildcheck was still queued when I re-reviewed. I am not treating that as a source-level blocker from Daniel's side.
Conclusion: can merge
- Blocking items
- None from my source-level re-review on the latest head.
- Suggested but non-blocking follow-up
- Tighten the new tests so the complete event sequence is asserted explicitly.
Overall, this revision fixes the main correctness problem from the previous review, keeps backward compatibility intact, and is in mergeable shape from Daniel's side.
Refer to: #9842
Purpose of this pull request
This PR implements the feature for reporting non-terminal job states.
Does this PR introduce any user-facing change?
Yes.
Users can receive non-terminal job state events by enabling the
report-non-terminal-job-stateoption.How was this patch tested?
Added a test in
JobStateEventTest.Check list
New License Guide
incompatible-changes.mdto describe the incompatibility caused by this PR.