Repository navigation
Conversation
|
|
||
| private static ExecutorService newProbeExecutor() { | ||
| ThreadPoolExecutor executor = new ThreadPoolExecutor( | ||
| MAX_CONCURRENT_PROBES, MAX_CONCURRENT_PROBES, 60L, TimeUnit.SECONDS, |
There was a problem hiding this comment.
Following up on the blocking-call concern raised in #5403: the four-thread limit bounds active probes, but the LinkedBlockingQueue is unbounded.
If all four probes ignore interruption, subsequent checks queue and time out without running. Cancelling their futures does not remove those tasks from this executor's queue.
when i reproduced this with the checker implementation, three subsequent requests left three cancelled tasks queued, and the healthy process was never probed.
Could we bound pending work and remove cancelled queued tasks?
There was a problem hiding this comment.
Thanks for reproducing this, you're right.
- The queue is now bounded (64 entries). A probe that doesn't fit is rejected right away with a new reason,
PROBE_UNAVAILABLE. - Cancelled probes are purged from the queue before the request returns.
- A probe that never got a thread is also reported as
PROBE_UNAVAILABLE, withoutprobeTookMs. Only a probe that started and ran past the deadline isPROBE_TIMEOUT.
The executor is shared across requests, so while all four threads are held, a healthy interpreter still can't be probed and gets PROBE_UNAVAILABLE. What the change guarantees is that pending work stays bounded and the reason tells this apart from a probe that timed out. Limiting how long a thread is held would need timeouts on the launcher calls themselves (e.g. the Kubernetes API request), so I'd leave that for a follow-up.
| </table> | ||
|
|
||
| <br/> | ||
| ### Health check an interpreter |
There was a problem hiding this comment.
Thanks for documenting the local/YARN limitation in the PR description. The same distinction appears relevant to Kubernetes: isRunning() checks the Pod phase and started, rather than a response from the interpreter.
This means healthy=true / reason=OK can be returned without establishing interpreter reachability, while the API documentation describes the result as whether the interpreter answered.
Could we document the launcher-specific guarantees in the API docs and avoid presenting OK as confirmed reachability?
There was a problem hiding this comment.
Agreed, and it applies beyond Kubernetes: no launcher's check gets a reply from the interpreter service.
- The docs now define
healthy/OKas the launcher reporting the interpreter as running, and list per launcher what is actually checked. - Groups that were checked now carry
checkMethod(e.g.KUBERNETES_POD_PHASE,TCP_CONNECT), so a caller can see whatOKis based on.
I kept the healthy / OK names to match the ticket, but the docs no longer present OK as confirmed reachability.
…h check looked at
What is this PR for?
After restarting an interpreter from the setting page there is no way to ask whether it is reachable. The badge on that page is the dependency download status (
InterpreterSetting.Status), which the code that starts and stops processes never touches, so it stays green whether the process is gone, stuck, or was never started. The only remaining way to find out is to run a paragraph, and for Spark that means the check itself takes cluster resources.This adds a probe that a user asks for explicitly:
Review points:
isRunning()takes no timeout, and its cost is not uniform: local and yarn read memory, docker opens a socket with a hardcoded one second timeout, and the k8s launcher asks the kube-apiserver through a client built with library defaults (10s per request, up to 10 retries with backoff). The thrift path is worse, since the socket is created without a timeout and the call is retried three times. So the probes run on another thread, and the request stops waiting after a budget shared by the whole setting. That budget is a 3 second constant. The number itself is arbitrary, so please suggest a more meaningful one and I will change it.System.exit, so a stuck non daemon thread would delay it.NOT_RUNNINGrather than as a failure. The frontend sub-tasks need that distinction to render something other than a red badge.isAlive, but the interface documentsisRunningas "the interpreter can communicate with server" whileisAliveonly says a process exists, sohealthyfollowsisRunningand both values are reported. The ticket also names two outcomes, healthy and unhealthy, which the response keeps as thehealthyflag; thereasonnext to it is what lets a caller tell a setting that was never started from one that timed out. Happy to reduce it if you prefer the literal reading.isRunning()reads in process state, so an interpreter that is up but no longer answering is still reported healthy there. Only docker, k8s, and existing process check from outside. A thrift level ping would answer that properly, but it needs a schema change and has no bound of its own, so it is left out.Out of scope, on purpose:
GET /api/sessioncallsisRunning()per session on a timer and has the same cost problem, but fixing it is a separate change.What type of PR is it?
Feature
Todos
InterpreterHealthCheck, the response model, built through factory methods sohealthycannot disagree withreasonInterpreterHealthChecker, which probes the groups of a setting under one deadlinePOST /api/interpreter/setting/{settingId}/healthcheckendpoint with the note based authorization that restart already usesdocs/usage/rest_api/interpreter.mdWhat is the Jira issue?
How should this be tested?
Included tests, all passing on current master:
InterpreterHealthCheckerTest, 7 tests. Covers the deadline, a slow group not hiding a fast one, group order, not probing a launching group, not starting an interpreter to answer, and a single remote call in the healthy case. (7 passed, 0 failed)InterpreterRestApiTest, 2 added. A health check of an unused setting returnsNOT_RUNNINGwith no groups and leaves the setting without one, and an unknown setting returns 404. (13 passed, 0 failed)License check:
./mvnw clean org.apache.rat:apache-rat-plugin:check -Prat -pl zeppelin-serverreports 0 unapproved.Manually, on a running server:
Right after a restart this answers
NOT_RUNNINGwithout starting anything. Run a paragraph first and the same call reports the group as healthy.Screenshots (if appropriate)
N/A, REST only.
Questions:
docs/usage/rest_api/interpreter.md.