andygrove opened a new issue, #2224:
URL: https://github.com/apache/datafusion-ballista/issues/2224

   **Describe the bug**
   
   In push-based scheduling, an executor registers with the scheduler before 
its own gRPC server has bound its listening socket. The scheduler's 
registration handler dials back to the executor to verify connectivity, so if 
it wins the race it gets `ConnectionRefused`, registration fails, and the 
executor process exits.
   
   The ordering is already flagged by a `TODO` in the code:
   
   - `executor_server::startup` (`ballista/executor/src/executor_server.rs`) 
logs `"... Rust Executor Grpc Server listening on ..."` and then spawns the 
tonic server with `tokio::spawn(...serve_with_shutdown(addr, ...))`. The bind 
happens inside that spawned task, so the log line is emitted before the socket 
exists.
   - Immediately afterwards, step 2 calls `register_executor`, with the 
standing comment: `// TODO the executor registration should happen only after 
the executor grpc server started.`
   - On the scheduler side, `ExecutorManager::register_executor` 
(`ballista/scheduler/src/state/executor_manager.rs`) calls `test_connectivity`, 
which is a single `ExecutorGrpcClient::connect(...)` with no retry and no 
backoff.
   - If that connect loses the race, registration returns an error, and 
`executor_process` treats it as fatal ("If there is executor registration error 
during startup, return the error and stop early"), so the executor exits rather 
than retrying.
   
   **To Reproduce**
   
   Observed in CI on the new HA chaos harness (`cargo test -p ballista-chaos 
--test ha`), in `baseline_matches_local_datafusion::case_2_aqe_on`. Two 
executors were started, one registered fine, the other lost the race and died, 
so the harness timed out:
   
   ```
   timed out waiting for 2 executors to register
   ```
   
   executor-1 log:
   
   ```
   INFO  ballista_executor::executor_server] Ballista v54.0.0 Rust Executor 
Grpc Server listening on 127.0.0.1:42635
   ERROR ballista_executor::executor_server] Executor registration failed due 
to: Grpc error: code: 'Internal error',
     message: "Fail to do executor registration due to: Internal Ballista 
error: Failed to register executor at
     127.0.0.1:42635, could not connect: tonic::transport::Error(Transport, 
ConnectError(ConnectError("tcp connect error",
     127.0.0.1:42635, Os { code: 111, kind: ConnectionRefused, message: 
"Connection refused" })))"
   ```
   
   scheduler log, same second:
   
   ```
   INFO  ballista_scheduler::scheduler_server::grpc] Received register executor 
request for ExecutorRegistration { id: "09332458-...", grpc_port: 42635, ... }
   ERROR ballista_scheduler::scheduler_server::grpc] Fail to do executor 
registration due to: Internal Ballista error:
     Failed to register executor at 127.0.0.1:42635, could not connect: ... 
ConnectionRefused ...
   ```
   
   It is timing-dependent, so it reproduces rarely and mostly on loaded 
machines. It is not specific to the chaos harness: any push-staged deployment 
where the executor is slow to reach the bind can hit it, and the consequence 
there is an executor that exits at startup instead of joining the cluster.
   
   **Expected behavior**
   
   An executor that is otherwise healthy should always succeed in registering. 
Its gRPC listener should be accepting connections before it tells the scheduler 
about itself.
   
   **Additional context**
   
   Two candidate fixes, not mutually exclusive:
   
   1. Bind synchronously in `executor_server::startup` before registering, i.e. 
create the `TcpListener` (or `TcpIncoming`) on the current task, then hand it 
to `serve_with_incoming_shutdown` in the spawned task. This closes the race at 
the source and lets the "listening on" log line tell the truth. It also removes 
the existing `TODO`.
   2. Give `ExecutorManager::test_connectivity` a short bounded retry (a few 
hundred milliseconds) so a marginally slow executor is tolerated rather than 
rejected outright.
   
   (1) alone fixes the local case. (2) additionally helps where the executor is 
on another host and is still coming up.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to