Write BEP-1073: stateless AppProxy coordinator
- Dominant language
- Python
- Stars
- 670
- Forks
- 183
- Avg merge
- 17h 7m
- Merged PRs (30d)
- 358
Description
Write BEP-1073 defining how the AppProxy coordinator becomes stateless. Reserve 1073 in proposals/README.md, then write the document on branch bep/1073-appproxy-stateless.
What the BEP must answer
1. State ownership map. Per coordinator table (endpoints, circuits, workers, worker_app_filters, tokens), where the state moves and why. Include the fact that occupied_slots becomes derived from etcd and its drift reconciler disappears.
2. Declarative apply API. Replace the delta API (POST /v2/endpoints/bulk/routes/register and /unregister) with a per-endpoint desired-state PUT. Delta calls diverge permanently when one is lost and are unsafe to retry; a declarative push is idempotent, so retries and sweeps reuse the same call. The API takes domain terms (worker, routes, health check), not Traefik keys, so the coordinator keeps ownership of rendering routers/services/middlewares. Serializing pushes per endpoint in the manager leader loop removes the ordering problem without any fencing token.
3. Interactive app allocation. Today the manager calls POST {wsproxy}/v2/conf (services/session/service.py:1458) and only receives a token, which it returns to the WebUI (api/rest/session/handler.py:1109). The browser then calls GET /v2/proxy/{token}/{session_id}/add (api/proxy.py:240), and only at that point does the coordinator pick a worker, allocate a port or subdomain, create the circuit and publish it. The manager never learns the circuit id or port. The BEP must define how allocation moves ahead of the client: the manager allocates at conf time and applies, while /add degrades to an etcd lookup that returns the URL, so the client contract is unchanged and the coordinator stays stateless.
4. Worker registry on etcd leases. Workers keep registering to the coordinator, which records them in etcd under a lease. The manager reads that inventory for allocation. This replaces the DoCheckWorkerLostEvent polling that sets WorkerStatus.LOST (server.py:428, 499).
5. Convergence model. Manager-side sweep frequency, orphan cleanup ownership, and whether an etcd generation key can replace a periodic full sweep by triggering a full resync only after an etcd restart or restore. State plainly that the reconcile loop relocates rather than disappears: lost apply calls, orphaned keys, and etcd data loss all need a full comparison.
6. Migration. How live circuits in existing coordinator databases are imported, cutover ordering, and an explicit note that this cannot be backported to 26.4.
7. Removals. api/health.py answers every route as unknown with health_status None, a leftover from when the coordinator probed kernels itself. PUT /v2/endpoints/{endpoint_id}/health-check has no corresponding method in the manager AppProxy client on main or 26.4, so nothing calls it.
Prior art: BEP-1005 Unified AppProxy.
Gate: write the Korean draft first and get confirmation before producing the English document.
JIRA Issue: BA-7124
Contributor guide
Research direction
Reserve BEP-1073 in proposals/README.md, then read BEP-1005 and the referenced AppProxy paths: services/session/service.py, api/rest/session/handler.py, api/proxy.py, server.py, and api/health.py. Produce the Korean draft first for confirmation, then an English BEP covering state ownership, declarative allocation, leases, convergence, migration, and removals, including the required branch name and 26.4 backport note.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend-api-design, distributed-systems, documentation
- Issue type
- Documentation
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100