[Improvement-17330][K8s] Replace job watcher with informer - #18358
[Improvement-17330][K8s] Replace job watcher with informer#18358det101 wants to merge 38 commits into
Conversation
746825e to
b65a890
Compare
|
b65a890 to
ab3aeef
Compare
fc4f603 to
273ecec
Compare
fc72e84 to
38650b9
Compare
|
Upgrading Fabric8 from version 6.4 to 6.0: The BOM upgrade was found to affect all Kubernetes clients, resulting in a significant impact. Modifications were made, but still based on version 6.0. @SbloodyS @ruanwenjun |
SbloodyS
left a comment
There was a problem hiding this comment.
This still does not fully replace the old Watcher.onClose failure path. In Fabric8 6.0, SharedIndexInformer.start() completes from Reflector.listSyncAndWatch(), but Reflector does not compose the watch future returned by startWatcher(); later non-HttpGone watch closures only set running=false and do not complete this start future exceptionally. For non-timeout tasks, awaitJobCompletion() can therefore block forever instead of failing the task as the old onClose(WatcherException) did. We need an explicit monitor/failure path for informer/watch stopping, or another way to count down the latch when the informer can no longer observe the Job.
Hi, to address the concern that awaitJobCompletion() may block forever when the informer stops observing the Job in Fabric8 6.0, my approach is: Primary: SharedIndexInformer handles ADD/UPDATE/DELETE. Does this approach work for you? |
|
I agree that polling the Job status via GET is a useful safety net when informer events are missed and the Kubernetes API is still reachable. However, I think this still does not fully cover the old Could we add a bounded failure policy for continuous polling errors, or another explicit fatal/stopped informer path, so the task can fail instead of waiting forever? A unit test for “informer started, no terminal event, GET keeps failing, no timeout strategy” would also help cover this case. |
5b588a3 to
9d67b03
Compare
|
Good catch — you're right that logging poll errors alone doesn't cover the old |
SbloodyS
left a comment
There was a problem hiding this comment.
I found two correctness issues in the current implementation:
- [P1] Treat a missing JobStatus as a running state
File: dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/k8s/impl/K8sJobMonitor.java
Around lines 235–240
Kubernetes may legitimately return a newly created Job whose status is still null. This is especially relevant now because onAdd evaluates the Job immediately.
getK8sJobStatus() currently dereferences job.getStatus() without a null check. The ADD handler will therefore throw a NullPointerException. The polling path has a more serious consequence: the same valid response is counted as a polling failure, and three responses with a null status will incorrectly fail the task even though the API requests succeeded and the Job may simply still be pending.
Please treat a null Job or JobStatus as RUNNING_CODE and add a test using a Job without a status object.
- [P2] Seal the terminal result when timeout or monitor setup fails
File: dolphinscheduler-task-plugin/dolphinscheduler-task-api/src/main/java/org/apache/dolphinscheduler/plugin/task/api/k8s/impl/K8sJobMonitor.java
Around lines 95–101
The exception handlers write EXIT_CODE_FAILURE directly but leave completed false. Consequently, after a timeout or another monitoring exception, an informer callback or an already-running polling request can still call completeOnce(...) and overwrite the failure with success.
This race is particularly possible at the timeout boundary: await() times out, the catch block records failure, and a concurrently queued terminal UPDATE then records success because it can still change completed from false to true.
Please route these failure paths through the same atomic completion mechanism, for example by calling completeOnce(completed, countDownLatch, taskResponse, EXIT_CODE_FAILURE, jobName). A timeout-versus-success concurrency test would also help prevent regressions.




Was this PR generated or assisted by AI?
YES
Purpose of the pull request
fix #17330
Brief change log
Verify this pull request
This change added tests and can be verified as follows:
./mvnw -pl dolphinscheduler-task-plugin/dolphinscheduler-task-api clean test -Dtest=K8sTaskExecutorTest
busyboxshort task (sleep 10) succeeds end-to-endsleep 2400) does not fail withtoo old resource version([Improvement][K8s] too old resource version #17330)Pull Request Notice
Pull Request Notice
If your pull request contains incompatible change, you should also add it to
docs/docs/en/guide/upgrade/incompatible.md