Repository navigation
Commit 8d2773c
fix: Bind metrics, REST registry, ui, and lineage servers dual-stack (#6886)
* fix: Bind metrics and REST registry servers dual-stack
The Prometheus metrics server and the REST registry server both hardcode
IPv4-only binds ("" and "0.0.0.0"), so neither is reachable on IPv6-only
or dual-stack clusters, unlike the gRPC registry server which already
binds "[::]" unconditionally. Add an IPv6 probe (feast.utils._ipv6_available)
and bind both servers to the IPv6 wildcard when available, falling back to
IPv4-only on hosts without IPv6 support (e.g. kernels booted with
ipv6.disable=1, where socket(AF_INET6) raises EAFNOSUPPORT).
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Signed-off-by: dbbvitor <[email protected]>
* style: Add type hints to _make_metrics_httpd, restore stray formatting
Add type hints to _make_metrics_httpd per AGENTS.md, and hoist its stdlib
wsgiref/socket imports to module level since there's no import-cycle risk.
Also restore a blank line in test_metrics.py that a mis-resolved ruff
(stale 0.6.9 from PATH, not the pinned 0.16.0) stripped during an earlier
commit's pre-commit hook run.
Signed-off-by: dbbvitor <[email protected]>
* fix: Bind the REST registry server via a pre-built dual-stack socket
uvicorn's host="::" binds IPv6-only: asyncio's loop.create_server() sets
IPV6_V6ONLY=1 on any socket it creates itself from a host string, which
would silently drop IPv4 clients on every host, not just IPv6-less ones.
Bind the socket ourselves (IPV6_V6ONLY=0, falling back to IPv4-only when
the host has no IPv6) and hand it to uvicorn via Server.run(sockets=...),
the same pattern used for socket-activated Gunicorn workers.
Signed-off-by: dbbvitor <[email protected]>
* fix: Bind the ui and lineage servers dual-stack too
start_server (ui_server.py) and start_lineage_server (lineage_server.py)
both call uvicorn.run(app, host=host, port=port) directly. A plain
host="::" there binds IPv6-only -- asyncio's loop.create_server sets
IPV6_V6ONLY=1 on any socket it creates itself from a host string -- which
silently drops IPv4 clients on every host, not just IPv6-less ones. This
is the same bug the metrics and REST registry servers had, fixed
separately on fix/sdk-dual-stack-binds.
Add feast.utils._make_dual_stack_socket(port), a shared version of
_make_rest_socket's pre-bound-socket approach, and route both servers
through it when host == "::": build the socket with IPV6_V6ONLY cleared
and hand it to uvicorn.Server(config).run(sockets=[sock]) instead of
uvicorn.run(host=...). Any other host keeps today's plain uvicorn.run
behavior unchanged.
This closes the gap the Operator's dualStack option (feat/operator-dual-stack)
depends on: without this fix, enabling dualStack for the ui/lineage
services would have silently regressed their IPv4 reachability instead of
adding IPv6.
Signed-off-by: dbbvitor <[email protected]>
* refactor: Share one dual-stack socket builder across REST, ui, lineage
_make_rest_socket and the new _make_dual_stack_socket had identical
bodies. Delete _make_rest_socket and have rest_registry_server.py call
the shared feast.utils helper instead, so there is one implementation
for all three uvicorn-based dual-stack servers.
Moves the real (port-0) end-to-end socket reachability test from
test_api_rest_registry_server.py to test_utils.py, targeting the shared
helper directly -- the ui and lineage code paths now get real IPv4/IPv6
reachability coverage from the same test, not just mocks.
Signed-off-by: dbbvitor <[email protected]>
* fix: Close the dual-stack socket on bind failure, cache IPv6 probe
An unguarded bind()/listen() leaked the socket fd on failure; wrap the
setup in try/except so it closes before re-raising. Also cache the
IPv6 support probe with lru_cache since it can't change at runtime.
Signed-off-by: dbbvitor <[email protected]>
* feat: Expose a host override on the REST registry server
RestRegistryServer.start_server() gains a host param, defaulting to
"::" (dual-stack, unchanged behavior). Any other value falls back to
plain uvicorn.run(host=host), letting deployments opt out of
dual-stack binding. Threaded through FeatureStore.serve_registry() and
a new --host/-h CLI flag on serve_registry.
Signed-off-by: dbbvitor <[email protected]>
* fix: Add a blocking parameter to _make_dual_stack_socket
setblocking(False) baked in an asyncio assumption invisible from the
function name, so a caller expecting a blocking socket would fail
silently. Default stays False for the existing asyncio-based callers.
Signed-off-by: dbbvitor <[email protected]>
---------
Signed-off-by: dbbvitor <[email protected]>
Co-authored-by: Claude Sonnet 5 <[email protected]>1 parent c5efecd commit 8d2773c
14 files changed
Lines changed: 788 additions & 35 deletions
File tree
- sdk/python
- feast
- api/registry/rest
- cli
- tests/unit
- api
- cli
- openlineage
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
26 | | - | |
| 26 | + | |
27 | 27 | | |
28 | 28 | | |
29 | 29 | | |
| |||
322 | 322 | | |
323 | 323 | | |
324 | 324 | | |
| 325 | + | |
325 | 326 | | |
326 | 327 | | |
327 | 328 | | |
| 329 | + | |
| 330 | + | |
328 | 331 | | |
329 | 332 | | |
330 | 333 | | |
331 | 334 | | |
332 | 335 | | |
333 | 336 | | |
| 337 | + | |
334 | 338 | | |
335 | | - | |
336 | | - | |
337 | | - | |
338 | | - | |
339 | | - | |
340 | | - | |
341 | | - | |
342 | | - | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
343 | 351 | | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
344 | 355 | | |
345 | | - | |
346 | | - | |
347 | | - | |
348 | | - | |
349 | | - | |
350 | | - | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
351 | 359 | | |
| 360 | + | |
| 361 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
225 | 225 | | |
226 | 226 | | |
227 | 227 | | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
228 | 236 | | |
229 | 237 | | |
230 | 238 | | |
| |||
234 | 242 | | |
235 | 243 | | |
236 | 244 | | |
| 245 | + | |
237 | 246 | | |
238 | 247 | | |
239 | 248 | | |
| |||
253 | 262 | | |
254 | 263 | | |
255 | 264 | | |
256 | | - | |
| 265 | + | |
257 | 266 | | |
258 | 267 | | |
259 | 268 | | |
| |||
272 | 281 | | |
273 | 282 | | |
274 | 283 | | |
| 284 | + | |
275 | 285 | | |
276 | 286 | | |
277 | 287 | | |
| |||
289 | 299 | | |
290 | 300 | | |
291 | 301 | | |
292 | | - | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
293 | 307 | | |
294 | 308 | | |
295 | 309 | | |
| |||
299 | 313 | | |
300 | 314 | | |
301 | 315 | | |
| 316 | + | |
302 | 317 | | |
303 | 318 | | |
304 | 319 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4765 | 4765 | | |
4766 | 4766 | | |
4767 | 4767 | | |
| 4768 | + | |
4768 | 4769 | | |
4769 | | - | |
| 4770 | + | |
| 4771 | + | |
4770 | 4772 | | |
4771 | 4773 | | |
4772 | 4774 | | |
4773 | 4775 | | |
4774 | 4776 | | |
4775 | 4777 | | |
4776 | | - | |
| 4778 | + | |
| 4779 | + | |
| 4780 | + | |
| 4781 | + | |
4777 | 4782 | | |
4778 | 4783 | | |
4779 | 4784 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
256 | 256 | | |
257 | 257 | | |
258 | 258 | | |
259 | | - | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
46 | 46 | | |
47 | 47 | | |
48 | 48 | | |
| 49 | + | |
49 | 50 | | |
50 | 51 | | |
51 | 52 | | |
52 | 53 | | |
53 | 54 | | |
54 | 55 | | |
55 | | - | |
| 56 | + | |
| 57 | + | |
56 | 58 | | |
57 | 59 | | |
58 | 60 | | |
| |||
583 | 585 | | |
584 | 586 | | |
585 | 587 | | |
| 588 | + | |
| 589 | + | |
| 590 | + | |
| 591 | + | |
| 592 | + | |
| 593 | + | |
| 594 | + | |
| 595 | + | |
| 596 | + | |
| 597 | + | |
| 598 | + | |
| 599 | + | |
| 600 | + | |
| 601 | + | |
| 602 | + | |
| 603 | + | |
| 604 | + | |
| 605 | + | |
| 606 | + | |
| 607 | + | |
586 | 608 | | |
587 | 609 | | |
588 | 610 | | |
| |||
633 | 655 | | |
634 | 656 | | |
635 | 657 | | |
636 | | - | |
637 | | - | |
638 | | - | |
| 658 | + | |
639 | 659 | | |
640 | 660 | | |
641 | 661 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1216 | 1216 | | |
1217 | 1217 | | |
1218 | 1218 | | |
| 1219 | + | |
1219 | 1220 | | |
1220 | | - | |
1221 | | - | |
1222 | | - | |
1223 | | - | |
1224 | | - | |
1225 | | - | |
1226 | | - | |
| 1221 | + | |
| 1222 | + | |
| 1223 | + | |
| 1224 | + | |
| 1225 | + | |
| 1226 | + | |
| 1227 | + | |
| 1228 | + | |
| 1229 | + | |
| 1230 | + | |
| 1231 | + | |
| 1232 | + | |
1227 | 1233 | | |
1228 | | - | |
| 1234 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
| 2 | + | |
2 | 3 | | |
3 | 4 | | |
4 | 5 | | |
| 6 | + | |
5 | 7 | | |
6 | 8 | | |
7 | 9 | | |
| |||
63 | 65 | | |
64 | 66 | | |
65 | 67 | | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
66 | 112 | | |
67 | 113 | | |
68 | 114 | | |
| |||
0 commit comments