Eason09053360 opened a new pull request, #73025:
URL: https://github.com/apache/airflow/pull/73025
## Why
`airflow standalone` prints "Airflow is ready" without checking the
component that serves the UI. `is_ready()` only looks at the scheduler, Dag
processor and triggerer heartbeats, so the banner fires while the API server is
still importing the app and binding its port. Developers follow the banner to
the browser and get a connection refused.
The check is not new. `is_ready()` gated on the port from the command's
introduction in #15826, and #20505 later fixed it to read the configured port
instead of a hard-coded 8080. #46942 ("Remove old UI and webserver") then
deleted the attribute holding the port but left the call that read it, so
`is_ready()` raised `AttributeError`; the follow-up hot-fix #47145 resolved
that by deleting the call rather than repointing it at the renamed `[api]
port`. `port_open` and its two tests have been unreachable since.
## What
`airflow-core/src/airflow/cli/commands/standalone_command.py`:
- `is_ready()` gates on `port_open` again, first in the chain so the three
heartbeat queries are skipped while the API server is still coming up.
- `run()` resolves `[api] port` once at startup, matching the shape the
pre-#47145 code used. Keeping the lookup out of the poll loop matters:
`conf.getint` raises on a malformed value, the loop only handles
`KeyboardInterrupt`, and the `command.stop()` / `command.join()` shutdown sits
after the `try` rather than in a `finally`, so an escape would leave all four
components running as orphans. With the lookup in `run()`, a bad `[api] port`
fails before anything is spawned.
- Two stale docstrings corrected: `is_ready()` claimed to be time-based,
which it has not been since #15826, and `port_open` still referred to the
webserver.
`airflow-core/tests/unit/cli/commands/test_standalone_command.py`: the
`is_ready` tests are consolidated into one parametrized test covering
port-open, a component not heartbeating, and port-closed. It asserts
`port_open` is called with the resolved port, and the port-closed case passes
an empty iterator so the short-circuit is pinned. A new test covers the config
resolution in `run()`. Reverting the source change fails all four.
### Deliberately not in this PR
`port_open` is restored as it was, so its pre-existing limitations come back
with it and are worth a maintainer's call:
- It probes `127.0.0.1` over IPv4 and ignores `[api] host`. The default
`0.0.0.0` is fine, but a user who binds a specific non-loopback address would
never see the banner.
- A TCP accept proves something is listening, not that it is this
standalone's API server. A stale process holding the port still yields a ready
banner.
- With `[api] workers > 1` or `server_type = gunicorn` the parent binds
before workers import the app, so the accept precedes app readiness.
All three point at the same deeper fix: polling `GET
/api/v2/monitor/health`, which is already the idiom in the Helm chart, breeze,
and `dev/verify_*_rc.sh`, and which would subsume the heartbeat checks too.
That is a larger change than restoring a lost gate, so I have kept it out.
Separately, `ready_time` latches and is never re-evaluated, so the banner
still makes a 3-second-stale claim, and standalone never notices a component
dying. Both are pre-existing and unchanged here.
`.github/workflows/basic-tests.yml` greps this banner, so that job now
genuinely depends on the API server binding.
### How to test
Run `airflow standalone` and confirm the banner appears only once
`http://localhost:8080` actually answers.
---
##### Was generative AI tooling used to co-author this PR?
- [X] Yes — Claude Code (Opus 5)
Generated-by: Claude Code (Opus 5) following [the
guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions)
--
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]