Skip to content

feat(BA-8443): push ingresses from the coordinator to api-delivery workers - #15833

Merged
jopemachine merged 3 commits into
mainfrom
feat/BA-8443-coordinator-ingress-push
Oct 23, 2026
Merged

jopemachine merged 3 commits into
mainfrom
feat/BA-8443-coordinator-ingress-push

Conversation

@jopemachine

@jopemachine jopemachine commented Oct 19, 2026 •

Copy link
Copy Markdown
Member

📚 Stacked PRs

Part of the AppProxy worker Ingress stack (epic BA-8433). Merge in order (bottom-up):

  1. 👉 feat(BA-8443): push ingresses from the coordinator to api-delivery workers #15833 — feat(BA-8443): push ingresses from the coordinator to api-delivery workers ← you are here
  2. feat(BA-8444): add the coordinator client that writes ingresses to Traefik etcd #15893 — feat(BA-8444): export ingresses from the coordinator to Traefik etcd

Resolves #15539 (BA-8443)

Summary

  • Coordinator API for the manager. Like the worker handler, it is an IngressHandler class with api_handler methods. Each route is wrapped with auth_required("manager"), and the handler takes IngressServiceCtx, a MiddlewareParam carrying only the IngressService:
    • POST /v2/ingress/upsert takes IngressUpsertRequest and answers 204. A success means every node holds every sent ingress, so there is nothing to return.
    • POST /v2/ingress/remove takes IngressRemoveRequest and answers 204.
  • IngressService groups ingresses by authority and reads the appproxy-worker group from service discovery. It pushes concurrently, with an AppProxyWorkerClient (feat(BA-8642): add the coordinator client that pushes ingresses to api-delivery workers #15915) on a session from the common ClientPool, to the endpoint of every node labelled ingress-delivery-mode=api for that authority (labels from feat(BA-8635): choose how the AppProxy worker receives ingresses #15890). An authority with no such node is skipped, since its workers read ingresses from Redis. It keeps no ingress state and needs no schema change.
  • Service discovery is read on redis, where the workers register; core_redis only moves the coordinator's own registration.
  • Failures:
    • The coordinator answers only after every push has settled, so a late push cannot land after the manager's next request.
    • If any push failed, it answers ApiDeliveryWorkerPushFailedError (502). data.failures holds the error body of each failed node:
    • Every push failure is a 502 because one request fans out to several nodes that can fail differently, e.g. one rejects a stale revision while another is down. A single 4xx would misreport the nodes that failed for another reason. The manager tells a rejection apart by failures[].type.
    • A malformed request body is answered 400 and a wrong token 401 by the coordinator itself, before any push.
    • Upsert with the same revision and remove are both safe to retry.

Not in this PR

  • The manager-side client that calls these endpoints.

Test plan

  • pants check / pants test on tests/unit/appproxy:: and src/ai/backend/appproxy::
  • tests/unit/appproxy/coordinator/services/test_ingress.py — pushes go to each authority's api-delivery nodes only; an authority with no node is skipped; a failed node fails the push after every node finishes; every failed node is reported in failures

🤖 Generated with Claude Code

@github-actions github-actions Bot added size:L 100~500 LoC comp:common Related to Common component comp:app-proxy Related to App Proxy component labels Oct 19, 2026
jopemachine added a commit that referenced this pull request Oct 19, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jopemachine
jopemachine changed the base branch from main to feat/BA-8440-internal-ingress-push-port October 19, 2026 04:35
jopemachine added a commit that referenced this pull request Oct 19, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jopemachine
jopemachine force-pushed the feat/BA-8443-coordinator-ingress-push branch from 2cbb6d9 to 5d0277b Compare October 19, 2026 04:56
jopemachine added a commit that referenced this pull request Oct 19, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jopemachine
jopemachine force-pushed the feat/BA-8443-coordinator-ingress-push branch from 5d0277b to 0965095 Compare October 19, 2026 05:58
jopemachine added a commit that referenced this pull request Oct 20, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jopemachine
jopemachine changed the base branch from feat/BA-8440-internal-ingress-push-port to main October 20, 2026 01:33
@jopemachine jopemachine changed the title feat(BA-8443): push ingresses from the coordinator to worker internal API ports feat(BA-8443): push ingresses from the coordinator to api-mode workers Oct 20, 2026
@github-actions github-actions Bot added size:XL 500~ LoC and removed size:L 100~500 LoC labels Oct 20, 2026
jopemachine added a commit that referenced this pull request Oct 20, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jopemachine
jopemachine changed the base branch from main to feat/BA-8443-worker-ingress-mode October 20, 2026 02:08
@github-actions github-actions Bot added size:L 100~500 LoC and removed size:XL 500~ LoC labels Oct 20, 2026
jopemachine added a commit that referenced this pull request Oct 20, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jopemachine jopemachine changed the title feat(BA-8443): push ingresses from the coordinator to api-mode workers feat(BA-8443): push ingresses from the coordinator to api-delivery workers Oct 20, 2026
@github-actions github-actions Bot added size:XL 500~ LoC and removed size:L 100~500 LoC labels Oct 20, 2026
Base automatically changed from feat/BA-8443-worker-ingress-mode to main October 20, 2026 03:00
jopemachine added a commit that referenced this pull request Oct 20, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jopemachine
jopemachine force-pushed the feat/BA-8443-coordinator-ingress-push branch from 96cfd2b to 23c7172 Compare October 20, 2026 05:30
jopemachine added a commit that referenced this pull request Oct 20, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jopemachine
jopemachine force-pushed the feat/BA-8443-coordinator-ingress-push branch from cdd09b4 to cf35298 Compare October 20, 2026 06:27
jopemachine added a commit that referenced this pull request Oct 20, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jopemachine
jopemachine force-pushed the feat/BA-8443-coordinator-ingress-push branch from cf35298 to 737550d Compare October 20, 2026 06:43
@jopemachine
jopemachine changed the base branch from feat/BA-8639-coordinator-secret-middleware to main October 20, 2026 06:43
jopemachine added a commit that referenced this pull request Oct 20, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jopemachine
jopemachine force-pushed the feat/BA-8443-coordinator-ingress-push branch from 74dad3c to f80751f Compare October 20, 2026 07:44
@jopemachine
jopemachine changed the base branch from main to feat/BA-8642-coordinator-worker-client October 20, 2026 07:44
@github-actions github-actions Bot added size:L 100~500 LoC and removed size:XL 500~ LoC labels Oct 20, 2026
jopemachine added a commit that referenced this pull request Oct 20, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jopemachine
jopemachine force-pushed the feat/BA-8443-coordinator-ingress-push branch from f80751f to 76eeb95 Compare October 20, 2026 07:50
jopemachine added a commit that referenced this pull request Oct 20, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jopemachine
jopemachine force-pushed the feat/BA-8443-coordinator-ingress-push branch from 76eeb95 to 07f4c6d Compare October 20, 2026 08:00
Base automatically changed from feat/BA-8642-coordinator-worker-client to main October 20, 2026 08:15
jopemachine added a commit that referenced this pull request Oct 20, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jopemachine
jopemachine force-pushed the feat/BA-8443-coordinator-ingress-push branch from 07f4c6d to 831017f Compare October 20, 2026 08:16
@github-actions github-actions Bot added size:XL 500~ LoC and removed size:L 100~500 LoC labels Oct 20, 2026
@jopemachine
jopemachine marked this pull request as ready for review October 22, 2026 04:26
@jopemachine
jopemachine requested a review from a team as a code owner October 22, 2026 04:26
Copilot AI balanced review requested due to automatic review settings October 22, 2026 04:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Startup initialization and delivery failure handling contain unresolved defects that can prevent service startup or leave worker state incorrect.

3 open issues
What changed in this PR

Adds the AppProxy coordinator’s manager-facing ingress API and stateless delivery to API-mode workers, providing the push path for the ingress stack.

Changes:

  • Adds authenticated upsert and remove endpoints with typed request context and responses.
  • Groups pushes by authority, discovers API-delivery workers, and uses the shared HTTP client pool.
  • Adds service tests for worker selection, skipped authorities, and delivery failures.
File Description
tests/​unit/​appproxy/​coordinator/​services/​test_ingress.py Tests worker selection and push failures.
tests/​unit/​appproxy/​coordinator/​services/​BUILD Registers the new service tests.
tests/​unit/​appproxy/​coordinator/​clients/​worker/​test_client.py Updates address fixtures and removes obsolete pool tests.
src/​ai/​backend/​common/​dto/​appproxy/​v2/​ingress/​response.py Adds the coordinator upsert response.
src/​ai/​backend/​appproxy/​coordinator/​types.py Declares ingress service and delivery dependencies.
src/​ai/​backend/​appproxy/​coordinator/​services/​ingress.py Discovers workers and dispatches ingress operations.
src/​ai/​backend/​appproxy/​coordinator/​server.py Wires routes, discovery, client pooling, and service lifecycle.
src/​ai/​backend/​appproxy/​coordinator/​dto/​context.py Provides request-scoped ingress service access.
src/​ai/​backend/​appproxy/​coordinator/​dto/​__init__.py Initializes the DTO package.
src/​ai/​backend/​appproxy/​coordinator/​clients/​worker/​client.py Uses typed addresses and externally managed sessions.
src/​ai/​backend/​appproxy/​coordinator/​api/​ingress.py Defines manager-authenticated ingress endpoints.
changes/​15833.feature.md Records the new coordinator ingress API.

Review effort: Balanced

Comment thread src/ai/backend/appproxy/coordinator/server.py
Comment thread src/ai/backend/appproxy/coordinator/services/ingress.py Outdated
Comment on lines +74 to +76
except ValueError:
# RedisServiceDiscovery raises ValueError for a group with no registered service.
workers = []
Comment thread src/ai/backend/appproxy/coordinator/api/ingress.py Outdated
Comment thread src/ai/backend/appproxy/coordinator/services/ingress.py
jopemachine and others added 3 commits October 22, 2026 16:42
… session

Drop AppProxyWorkerClientPool so the coordinator holds worker sessions in
the common ClientPool. The client takes the worker address as a
HostPortPair, asks for JSON error bodies, and reports a timeout as an
unreachable worker.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ivery workers

POST /v2/ingress/upsert and /v2/ingress/remove take ingresses or keys
from the manager, group them by authority, and push each group to every
worker node of that authority whose ingress delivery mode is api, found
through the worker service discovery on the AppProxy redis. Both answer
204. The coordinator answers after every push has settled, and reports
the failed nodes together in ApiDeliveryWorkerPushFailedError (502). It
keeps no ingress state.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp:app-proxy Related to App Proxy component comp:common Related to Common component size:XL 500~ LoC

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add the coordinator Ingress API and push to workers

3 participants