Skip to content

Reserve configured listeners before application startup - #2057

Draft
Brian Krabach (bkrabach) wants to merge 2 commits into
mainfrom
investigate/three-defects-1701-current
Draft

Brian Krabach (bkrabach) wants to merge 2 commits into
mainfrom
investigate/three-defects-1701-current

Conversation

@bkrabach

@bkrabach Brian Krabach (bkrabach) commented Nov 14, 2026 •

Copy link
Copy Markdown
Collaborator

Change

Addresses #1701 at the CLI's listener-acquisition boundary. CPython 3.13 drops EADDRNOTAVAIL while binding and can raise an errno-less OSError; previously this bypassed CLI guidance after app construction had already started diagnostics and background controllers.

  • Reserve and retain the real configured listening sockets before settings migration, runtime configuration loading or app construction; pass those same sockets to aiohttp without host/port rebinding. Server settings validation and matching TLS material loading still precede socket acquisition.
  • Require success for every configured bind entry. Preserve per-name unavailable-family tolerance, passive stream resolution, IPv6-only/scope behavior and POSIX reuse without enabling Windows reuse or SO_REUSEPORT.
  • Scope actionable OS guidance to acquisition and name resolution. DNS errors cannot collide with ordinary errno guidance; unexpected application/resource errors retain their identity.
  • Close all held descriptors on failure, cancellation, failed later site attachment or ordinary shutdown. Preserve actual publishing-owner refusal, TLS/origin checks, task-runner attachment and authenticated HTTP readiness.
  • Document the TCP-queued-before-HTTP-ready construction window. No new readiness protocol, retry watcher, lifecycle registry or server/diagnostics framework.

Supervisor policies are deliberately unchanged: launchd KeepAlive continues to retry while a VPN address is unavailable. This does not eliminate process retries or rewrite service definitions or historical captures. No merge, version, release or live adoption is included. Independent plan review preceded implementation; independent results/validation review remains pending with the integration owner.

Validation

Source: accepted base 90cc4f2586dfc9db6826daae26ad18c2feb4ec7e; production change 96fb7b945c26c21cf7ef7378ab9c437ceca00522, followed by test-fixture-only correction a0d86cff342c62e75f8d64e915bab8b4b59d18d9, tree ca8c6e95a119997910fc0931ed6af0b50ff9be86. Isolated managed Linux aarch64, Python 3.13.16, locked aiohttp 3.14.4; no host bootstrap or live service-manager operation.

  • Initial focused suite: 307 passed, 7 skipped, 2 existing ACP deprecation warnings, 23.09s. Includes listener regressions, CLI/deployment/ownership, TLS/update-readiness and affected Windows service/task caller controls.
  • Final changed-boundary check: 49 passed, zero skipped, 10.44s, after aligning the IPv6 option guard with inspected asyncio behavior, strengthening directory-state/factory-failure assertions and adding platform-relative wildcard and localhost checks. All 3,871 tracked blobs/modes of the candidate match its tested source snapshot. Passing unchanged controls above are reused, not reported as rerun at the final source.
  • Original isolated investigation retained 15 passed / 4 intentional strict xfails, plus one tightened real-CLI xfail: the unavailable-guidance and capture promises were actually unmet on the accepted base. Those xfails are removed; the candidate cases pass.
  • Real public CLI + real app/fake runtime: failed numeric bind produces concise guidance and zero captures; three failed starts leave no file/directory changes except the existing repair lock and never reach migration/app construction. A later invocation queues TCP during construction but fails the real authenticated HTTPS health probe until ready, then records one app start, starts no conversation runtime and shuts down normally via owned SIGINT.
  • Same-object/port handoff, real occupied-owner survival, IPv6-only, scoped-address identity, duplicate/alias behavior, platform-relative wildcard overlap, DNS errno collision, EACCES/EADDRINUSE, EIO/EMFILE and descriptor cleanup are covered. TCP readiness is explicitly not substituted for authenticated HTTPS health.
  • The initial native Windows lane at 96fb7b945 failed, after the cold-default cell passed: its foreground audit guard rejected socket.getaddrinfo from the new acquisition path. Original run 43608166820, job 132487468908, foreground artifact 14119362709 remain failed evidence. The installed test candidate was GitHub's synthetic merge a993cb72 into then-main 0a54a81c, not the isolated branch alone; its CLI bytes match this branch exactly.
  • The test-only correction replaces the obsolete asyncio-only binding allowance with exact loaded-helper numeric 127.0.0.1 / configured-port / passive-stream resolution once, followed by that helper's same socket object. Unknown network, hostname/DNS, UDP, wrong caller/options/object/port and repeated attempts remain denied. 97 foreground fixture tests passed, zero skips, including actual child-process audit-hook admission and unowned same-target-resolution denial. All 3,871 candidate files/modes match the tested snapshot; production code is unchanged by this correction.
  • Corrected native Windows lane passed: run 43613019349, job 132502388227, foreground artifact 14121087147, installed synthetic candidate 298ac1d4 / tree 32627d09. Both the native cold-default step and installed foreground CLI step succeeded. The original report confirms setup/status/export/serve/open, cookie-CSRF replay, export fingerprint, real default runtime, public entry, TLS stability, graceful cleanup, listener closure and repair-lock release; zero unknown network attempts. One existing attested optional IPv6 capability probe was denied as intended. Outer jobs settled, scratch removed, and the report's publicAcceptance:false limit remains.

The three measured failed warm in-process CLI invocations took 4.967 / 2.581 / 2.702 ms in the final fixture, with fixed synthetic config/TLS inputs. This is not cold-process launch cost, a native launchd cadence measurement or a general claim that retries are cheap; the regression promise is zero app startup work/state effects on bind failure.

The seven skipped Linux-hosted controls require native Windows TokenUser, owned launch guard/descendant settlement, native command-line parsing, opt-in Task Scheduler, passive process handles, owner-table listener identity or Toolhelp ancestry. They remain skips, not retroactively passed. The separate native CI proof is bounded installed foreground CLI evidence, not universal native Windows/device/background-launch acceptance. Native macOS/Tailscale/launchd cadence and return-of-interface recovery and live adoption are not claimed. All three managed implementation/correction test environments were removed after source/raw/JUnit export; exact private operation receipts are retained with the integration owner rather than added to the repository.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant